<?xml version="1.0"?>
<rss version="2.0">

<channel>
	<title>Deb.News</title>
	<link>https://deb.news</link>
	<language>en</language>
	<description>Deb.News - https://deb.news</description>


<item>
	<title>Steinar H. Gunderson: Decompilation patterns, part 4: range comparison</title>
	<guid>http://blog.sesse.net/blog/tech/2026-10-07-16-21_decompilation_patterns_part_4_range_comparison.html</guid>
	<link>http://blog.sesse.net/blog/tech/2026-10-07-16-21_decompilation_patterns_part_4_range_comparison.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/sesse.png&quot; width=&quot;74&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Today, we&#39;re looking at a rewrite that rarely differs for matching,
but can mean quite a lot for understanding the code. Say that you
have a signed variable and the compiler has suddenly decided to make
an unsigned comparison:&lt;/p&gt;

&lt;pre&gt;    if ((u32) (x - 4) &amp;lt; 2) {
&lt;/pre&gt;

&lt;p&gt;What&#39;s happening is that it uses a controlled overflow to do two
signed comparisons using one unsigned comparison. How does this work?&lt;/p&gt;

&lt;p&gt;Since the comparison is unsigned, this is trivially equivalent
to the first expression:&lt;/p&gt;

&lt;pre&gt;    if ((u32) (x - 4) &amp;gt;= 0 &amp;amp;&amp;amp; (u32) (x - 4) &amp;lt; 2) {
&lt;/pre&gt;

&lt;p&gt;and since negative numbers compare larger than 6 in unsigned comparisons,
nothing prevents us from adding 4 on each side of the inequality signs:&lt;/p&gt;

&lt;pre&gt;    if ((u32) (x) &amp;gt;= 4 &amp;amp;&amp;amp; (u32) (x) &amp;lt; 6) {
&lt;/pre&gt;

&lt;p&gt;which is, for the same reason, equivalent to:&lt;/p&gt;

&lt;pre&gt;    if (x &amp;gt;= 4 &amp;amp;&amp;amp; x &amp;lt; 6) {
&lt;/pre&gt;

&lt;p&gt;which is what you probably should be writing.&lt;/p&gt; </description> 
	<pubDate>Wed, 07 Oct 2026 15:18:43 +0000</pubDate>

</item> 
<item>
	<title>Bits from Debian: Looking for artwork for the next Debian release: Forky</title>
	<guid>tag:bits.debian.org,2026-10-07:/2026/10/forky-artwork-cfp.html</guid>
	<link>https://bits.debian.org/2026/10/forky-artwork-cfp.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dwn.png&quot; width=&quot;77&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Each release of Debian has a shiny new theme which is visible on the installer,
the boot screen, the login screen and, most prominently, on the desktop
wallpaper. It&#39;s a very important part of a Debian release as it is usually the
first thing new users see when installing or booting the system for the first
time. Not only that, but also the first thing appearing when debianites share
their screen or connect to an external device when giving talks around the
world.&lt;/p&gt;
&lt;p&gt;As the most enthusiastic users will know, the forky - yes, that is the name of
the next stable version, Debian 14 - release cycle is rapidly approaching its
latter stages. This means we need to select the artwork shipping with forky
soon, really soon!&lt;/p&gt;
&lt;p&gt;And as with everything else in Debian, collecting artwork is a collaborative
effort which Debian shares with its community.  So, if you would like (or know
someone who would like) to create a desktop look and feel that will be seen by
trillions of people around the world - and in space! - be sure to send in your
artwork ASAP!&lt;/p&gt;
&lt;p&gt;The deadline for submissions is: 2026-11-26.&lt;/p&gt;
&lt;p&gt;For the most up to date details please refer to the &lt;a href=&quot;https://wiki.debian.org/DebianDesktop/Artwork/Forky&quot;&gt;Debian
wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the same time, we would like to thank Elise Couper for creating the
&lt;a href=&quot;https://wiki.debian.org/DebianArt/Themes/Ceratopsian&quot;&gt;Ceratopsian theme&lt;/a&gt; for
our last trixie release.&lt;/p&gt;
&lt;p&gt;And for the interested or the curious ones, the artwork is usually picked
based on which theme looks the most:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&#39;&#39;Debian&#39;&#39;: admittedly not the most defined concept, since everyone has their
  own take on what Debian means to them. Though, usually they all agree when
  something looks like Debian.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&#39;&#39;Plausible to integrate without patching core software&#39;&#39;: as much as we love
  some of the insanely looking themes, some would require heavy GTK+ theming
  and patching GDM/GNOME.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&#39;&#39;Clean and well designed&#39;&#39;: without becoming something that gets annoying to
  look at a year, or ten, down the road.  Examples of good themes include
  Emerald, Homeworld, Joy, Lines, softWaves and futurePrototype&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&#39;d like more information or details, please post to the &lt;a href=&quot;https://lists.debian.org/debian-desktop/&quot;&gt;Debian Desktop
mailing list&lt;/a&gt;.&lt;/p&gt; </description> 
	<pubDate>Wed, 07 Oct 2026 09:00:00 +0000</pubDate>

</item> 
<item>
	<title>Steinar H. Gunderson: Decompilation patterns, part 3: do-while-while</title>
	<guid>http://blog.sesse.net/blog/tech/2026-10-06-22-35_decompilation_patterns_part_3_do_while_while.html</guid>
	<link>http://blog.sesse.net/blog/tech/2026-10-06-22-35_decompilation_patterns_part_3_do_while_while.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/sesse.png&quot; width=&quot;74&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Today&#39;s decompilation pattern is a variation on yesterday&#39;s loop pattern,
because loops are important and tend to induce a lot of transformations
by the compiler. So assume you have code like this (perhaps after converting
a goto):&lt;/p&gt;

&lt;pre&gt;if (var_s0 &amp;gt; var_s1) {
  // Perhaps some other initialization stuff here
  do {
    ...
  } while (var_s0 &amp;gt; var_s1);
}
&lt;/pre&gt;

&lt;p&gt;Assuming there are no side effects from the initializations, a natural
candidate would be that the programmer instead wrote:&lt;/p&gt;

&lt;pre&gt;// Initialization stuff moved up here
while (var_s0 &amp;gt; var_s1) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;Remember to remove the old while so that it does not say &lt;code&gt;while (x) { ... } while (x)&lt;/code&gt;;
it won&#39;t tell you with a syntax error, but rather leave an infinite loop that will
mess up the generated code.&lt;/p&gt; </description> 
	<pubDate>Tue, 06 Oct 2026 21:35:00 +0000</pubDate>

</item> 
<item>
	<title>Russell Coker: A Power Case for a FOSS Phone</title>
	<guid>https://etbe.coker.com.au/?p=6307</guid>
	<link>https://etbe.coker.com.au/2026/10/06/power-case-foss-phone/</link>
     <description>  &lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;I want to use a FOSS phone running Debian as my daily driver and not use a non-free OS on my phone. &lt;a href=&quot;https://grapheneos.org/&quot;&gt;GrapheneOS [1]&lt;/a&gt; is a FOSS rebuild of Android, it’s a great project and I commend them for what they are doing. But I want a system where I have access to all the bits and where I can ssh in to it and manage it in the same way as all other Linux systems. Android is free software but it’s a closed design and the phones are expected to be appliances not full peers on the network. The Android native terminal emulator (AKA Linux development environment) is a nice feature, a VM with a default of 1GB of RAM but it’s still separate from the main OS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kdeconnect.kde.org/&quot;&gt;KDE Connect [2]&lt;/a&gt; is a system for KDE talking to phones, it is a great project and allows convenient interaction between a Linux PC and a phone. But in addition to that I’d like the option to ssh to my phone to send an SMS or have one sent from a cron job. &lt;a href=&quot;https://etbe.coker.com.au/2026/10/06/kdeconnect-dbus/&quot;&gt;I blogged about using the basic functions of Kdeconnect from the command-line [3]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I have had ongoing issues with the battery not lasting long enough on the PinePhonePro (PPP) and the Librem 5 (L5) which makes them unusable for my purposes. For a phone running Droidian I can have an open ssh session (with keep-alive packets) running overnight on Wifi without any problems while for the PPP or L5 an hour of reading an ebook (the least demanding use of a phone) will use most of the battery.&lt;/p&gt;
&lt;p&gt;I sent my FuriPhone back for warranty repair and it’s been almost a month with no follow up, so I need to have another option.&lt;/p&gt;
&lt;h2&gt;The Aim&lt;/h2&gt;
&lt;p&gt;The aim of this post is to develop a rough design for a battery case for either a L5 or a PPP, I have both phones and they are both capable of doing what I want apart from battery life. Also designing a case that basically works for both phones and has two variations of the CAD file for 3D printing is good to allow collaboration with people who use either phone. Protecting the phone from damage when dropped is also a core feature.&lt;/p&gt;
&lt;p&gt;I investigated commercial options. There are some reports of cases for other phones working, someone reported a PPP working well with a battery case for a Samsung S20 Ultra. The OtterBox uniVERSE Case for Samsung Galaxy XCover Pro is reported to fit the PPP so probably battery cases for the XCover Pro will also work. There are also universal power cases which have spring clips to fit a wide range of phone sizes, but they are much larger than other options and probably increase the risk of damage if the phone is dropped.&lt;/p&gt;
&lt;p&gt;At this stage I’m planning out the rough specs of a case that can be 3D printed to protect a phone while being easy to change the cells. The process of changing cells should be quick, easy, and not risk breaking anything. The hardware required should be affordable ($100AU plus some 3D printing seems reasonable) and should not require significant skills to assemble. After recent experiments with Thinkpad repair I’ve determined that I am not good at electronics by today’s standards so I plan to avoid anything difficult in that regard.&lt;/p&gt;
&lt;h2&gt;Battery Options&lt;/h2&gt;
&lt;p&gt;There are phone cases with batteries built in for the more common phones. A quick search on AliExpress turned up options for recent Pixel phones. They aren’t as common as they used to be as Android phones and iPhones generally have good battery life nowadays. Of course there aren’t such options for less common phones like the L5 and PPP.&lt;/p&gt;
&lt;p&gt;It is cheap and easy to buy a portable battery for charging phones, but that’s a separate bulky device and unless the connector is inside a protective case it leaves the phone vulnerable to catastrophic damage if dropped.&lt;/p&gt;
&lt;p&gt;So can a suitable battery case be designed and 3D printed?&lt;/p&gt;
&lt;h2&gt;Cheap Batteries&lt;/h2&gt;
&lt;p&gt;According to Wikipedia the 18650 LiIon cell is the most commonly used LiIon battery, that is 18mm in diameter and 65mm in length. For a phone case thinner batteries would be more convenient but economies of scale make the 18650 cheap to buy new and commonly available on the second hand market. The current prices on AliExpress (in Australian dollars) are about $8 per cell when buying 10 at a time. Most of the cells on AliExpress don’t have wires attached so they can be swapped in a carrier the way AA batteries are used, but the cells are symmetrical (no bump for positive) so the user has to take care of polarity. Chargers are around $22 for a 4 cell charger or $52 for a 12 cell charger.&lt;/p&gt;
&lt;p&gt;I’ve seen prices as low as $1 per cell on the second hand market, I haven’t investigated the amount of usable capacity in such cells. Probably the prices for chargers I’ve found aren’t the best available but they are good enough to start the design. 10 cells and a 4 cell charger is about $100. That’s about 130Wh while a 74Wh USB-C battery pack costs about $50. So the price per Wh is OK.&lt;/p&gt;
&lt;p&gt;I have read about an attempt to do this for the L5 with two of the batteries designed for the L5 in a case attached to it, so you have 3*L5 batteries. It’s an interesting approach but those batteries have poor value for money when compared to 18650 ($29US for 4500mAh compared to $8 for 3500mAh) and they also don’t ship them outside the US at this time. The 18650 batteries are available everywhere cheaply and have multiple uses.&lt;/p&gt;
&lt;h2&gt;How They Fit&lt;/h2&gt;
&lt;p&gt;According to my measurements the PPP is 76mm wide and the L5 is 73mm wide. That’s wide enough for 3*18mm or 4*18mm cells side by side arranged parallel to the long side of the phone or one 65mm long cell going across the phone with the necessary spring and wires.&lt;/p&gt;
&lt;p&gt;The L5 is about 151mm long and the PPP is about 5mm longer. So that means that for just the cells we could have 2 cells in a row in parallel to the long side of the phone giving a 2*3 or 2*4 array or we could have a row of 8 cells parallel to the short side of the phone.&lt;/p&gt;
&lt;p&gt;A quick search for controllers for a battery of LiIon cells that outputs USB-PD turned up one of the smaller ones as 40*28mm, &lt;a href=&quot;https://www.aliexpress.com/item/1005009329156591.html&quot;&gt;here is the AliExpress page [4]&lt;/a&gt;. So that means we could have a maximum of about 4 cells and the controller while leaving space for the camera. Looking at other similar items it seems that most of them take a large portion of the 73mm width available and take a bit less than 30mm height. The price range for DC-DC voltage converters ranges from about $3 to $20, the one I linked to is currently $8.&lt;/p&gt;
&lt;p&gt;The mass of 18650 cells is around 45g so 4 of them would be about 180g before counting the weight of the case and electronics. A L5 weighs 262g and a PPP weighs 220g so 180g of battery will make a significant difference, not an impossible difference but holding a PPP while reading an ebook is already annoying. Maybe the case could be designed to be easier to hold, a loop of wool attached to the top could be used to suspend the phone from one finger while the rest of the hand just keeps it steady.&lt;/p&gt;
&lt;p&gt;In a default configuration the L5 has a 4500mAh 3.8V battery and the PPP has a 3000mAh 3.8V battery. The 18650 cells have up to 4000mAh with 3500mAh being common. So 4 such cells could multiply the battery life of a PPP by a factor of 5 or a L5 by 4. That would not be enough to last for a whole day without charging so they need to be easy to swap.&lt;/p&gt;
&lt;p&gt;A 3 cell battery seems like a good option, 135g of batteries so the project overall wouldn’t even double the weight of the phone with battery case. As it doesn’t seem possible to put in enough cells to last a day of reasonable use (running a web browser, checking email, reading wikipedia, and having some IM systems checking for notifications) there doesn’t seem to be a benefit in trying to stuff the maximum number of cells in. Going to 4 or 5 cells doesn’t provide much benefit over 3 while increasing the weight and making the design more difficult. The modules for DC Voltage conversion often have configuration for the number of cells to be used so it wouldn’t be difficult to print a new case and reconfigure the Voltage converter.&lt;/p&gt;
&lt;h2&gt;Design&lt;/h2&gt;
&lt;p&gt;A case needs to provide protection as well as hold the batteries. The lack of cases for the L5 and PPP is a problem even without the extra weight of a battery pack increasing the kinetic energy of falling phone. Ideally a drop from 1M on to concrete would not cause any damage to the phone, destruction of the case is OK as it would be 3D printed and can be rebuilt easily.&lt;/p&gt;
&lt;p&gt;I think that a case where the phone slides in from the top would be best. To change cells one would slide the phone out and the cells would be immediately accessible with no divider between the phone and the cells. Sliding the phone in would hold the cells against the back of the case and as there is a gap of about 3mm on each side of the PPP between the display area and the edge of the phone there’s plenty of space for the case to wrap around it at the sides and bottom. At the top there would have to be some sort of plastic clip. The PPP only has buttons on the top right so the case can be snug on all sides apart from the top right. The L5 has switches at the top left and buttons at the top right so whatever clips on to the top would really need some strength to cover the fall flat on face case.&lt;/p&gt;
&lt;p&gt;The USB C plug would need to be held in place well enough to allow the phone to easily slide on to it but also be weak enough that it would move if a drop forced the phone out of the case.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:4961260&quot;&gt;Thingiverse has a design for a L5 case [5]&lt;/a&gt; (with several derivatives) and &lt;a href=&quot;https://www.thingiverse.com/thing:4933237&quot;&gt;a design for a PPP case [6]&lt;/a&gt;. Those cases could be used as starting points and then changed to store batteries and the voltage change circuit board. I have just learned that it’s possible to use rubberised material in a 3D printer which is apparently what those designs are for. If a case was printed with rubberised material the top could just stick in place after being pushed in.&lt;/p&gt;
&lt;h2&gt;Potential for Excessive Excitement&lt;/h2&gt;
&lt;p&gt;Having an exploding device in your pocket would be the exciting in a bad way. My initial idea was to have multiple 18650 cells in series. The problem is that if the cells have different capacity levels then one can run out before the rest and get to a deep discharge state which at a minimum causes damage to the cell.&lt;/p&gt;
&lt;p&gt;One way of minimising risk is to have only a single cell in use at one time, &lt;a href=&quot;https://www.aliexpress.com/item/1005007555665949.html&quot;&gt;here is a converter for a single cell to 5V [7]&lt;/a&gt;. It is possible to run multiple cells in parallel by simply wiring them together, but it’s recommended to make sure that the voltage difference between cells is less than 0.2V to avoid high current when connecting.&lt;/p&gt;
&lt;p&gt;The arrangement of cells is often referred to as nS or nP to refer to n cells in series or parallel. Aliexpress has a range of 1S to 6S devices. Some of the 2S devices have a connector for the mid point which permits separate voltage monitoring for both cells but there doesn’t seem to be anything equivalent for 3S or more. They also don’t appear to have anything to specifically manage 2P or 3P arrangements at the moment (they had a 3P board on sale when I looked into this last year).&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is a bigger project than I expected when I first started investigating it. I’ve played with FreeCAD which seems OK but will take a lot of learning and practice. Then I need to do more investigation into the DC-DC converters to find one that works well and is unlikely to start a fire.&lt;/p&gt;
&lt;p&gt;I will look into other phone options as well and keep chasing Furilabs people about my phone replacement.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1]&lt;a href=&quot;https://grapheneos.org/&quot;&gt; https://grapheneos.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2]&lt;a href=&quot;https://kdeconnect.kde.org/&quot;&gt; https://kdeconnect.kde.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3]&lt;a href=&quot;https://etbe.coker.com.au/2026/10/06/kdeconnect-dbus/&quot;&gt; https://etbe.coker.com.au/2026/10/06/kdeconnect-dbus/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[4]&lt;a href=&quot;https://www.aliexpress.com/item/1005009329156591.html&quot;&gt; https://www.aliexpress.com/item/1005009329156591.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[5]&lt;a href=&quot;https://www.thingiverse.com/thing:4961260&quot;&gt; https://www.thingiverse.com/thing:4961260&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[6]&lt;a href=&quot;https://www.thingiverse.com/thing:4933237&quot;&gt; https://www.thingiverse.com/thing:4933237&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[7]&lt;a href=&quot;https://www.aliexpress.com/item/1005007555665949.html&quot;&gt; https://www.aliexpress.com/item/1005007555665949.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;yarpp yarpp-related yarpp-related-rss yarpp-template-list&quot;&gt;

&lt;p&gt;Related posts:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2012/12/21/galaxy-s3-power-case/&quot; rel=&quot;bookmark&quot; title=&quot;Samsung Galaxy S3 First Review with Power Case&quot;&gt;Samsung Galaxy S3 First Review with Power Case&lt;/a&gt; &lt;small&gt;My new Samsung Galaxy S3 arrived a couple of days...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2013/01/24/power-supplies-wires/&quot; rel=&quot;bookmark&quot; title=&quot;Power Supplies and Wires&quot;&gt;Power Supplies and Wires&lt;/a&gt; &lt;small&gt;For some time I’ve been wondering how the wire size...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2024/04/29/usb-psus/&quot; rel=&quot;bookmark&quot; title=&quot;USB PSUs&quot;&gt;USB PSUs&lt;/a&gt; &lt;small&gt;I just bought a new USB PSU from AliExpress [1]....&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Tue, 06 Oct 2026 08:08:04 +0000</pubDate>

</item> 
<item>
	<title>Russell Coker: Kdeconnect DBUS</title>
	<guid>https://etbe.coker.com.au/?p=6310</guid>
	<link>https://etbe.coker.com.au/2026/10/06/kdeconnect-dbus/</link>
     <description>  &lt;p&gt;I’ve tested the DBUS interfaces for Kdeconnect (the system for connecting a KDE desktop to a phone or another computer). Unlike most DBUS interfaces it has a significant tree of interfaces so the busctl command to get the tree is important. Here’s the useful things I discovered:&lt;/p&gt;
&lt;pre&gt;# list basic interfaces for kdeconnect
qdbus6 org.kde.kdeconnect.daemon /modules/kdeconnect
# get tree of interfaces for kdeconnect
busctl --user tree org.kde.kdeconnect.daemon
# get list of devices
qdbus6 --literal org.kde.kdeconnect.daemon /modules/kdeconnect org.kde.kdeconnect.daemon.deviceNames
# list interfaces for a device (DEVID is a hex string from the above command)
qdbus6 org.kde.kdeconnect.daemon /modules/kdeconnect/devices/$DEVID
# get battery charge
qdbus6 org.kde.kdeconnect.daemon /modules/kdeconnect/devices/$DEVID/battery org.kde.kdeconnect.device.battery.charge&lt;/pre&gt;
&lt;p&gt;Sending an SMS apparently requires using the QVariantList type which is more pain than I wanted so I tried the kdeconnect-cli command. Here’s a quick summary of how to use it:&lt;/p&gt;
&lt;pre&gt;# list devices
kdeconnect-cli -l
# send a SMS
kdeconnect-cli -d $DEVID --send-sms &quot;the message&quot; --destination $NUMBER
# find device (ring)
kdeconnect-cli --ring -d $DEVID
# send a notification message
kdeconnect-cli --ping-msg &quot;this is the message&quot; -d $DEVID
# unlock and lock screen (only works on Debian devices for me not Android devices)
kdeconnect-cli --unlock -d $DEVID
kdeconnect-cli --lock -d $DEVID&lt;/pre&gt;
&lt;p&gt;There doesn’t seem to be support for making phone calls via kdeconnect which is a significant omission. It’s a very common situation to want to call a number that’s listed on a web site or in some other data source that’s easier to access on a PC than on a phone. The clipboard could be used but that’s needless pain.&lt;/p&gt;
&lt;div class=&quot;yarpp yarpp-related yarpp-related-rss yarpp-template-list&quot;&gt;

&lt;p&gt;Related posts:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2026/09/17/nheko-dbus/&quot; rel=&quot;bookmark&quot; title=&quot;Nheko DBUS&quot;&gt;Nheko DBUS&lt;/a&gt; &lt;small&gt;Nheko is my current favourite client for the Matrix IM...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2024/11/02/moving-between-devices/&quot; rel=&quot;bookmark&quot; title=&quot;Moving Between Devices&quot;&gt;Moving Between Devices&lt;/a&gt; &lt;small&gt;I previously wrote about the possibility of transferring work between...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2007/01/15/dbus-error/&quot; rel=&quot;bookmark&quot; title=&quot;dbus error&quot;&gt;dbus error&lt;/a&gt; &lt;small&gt;Strange dbus error from the KDE power monitoring tool...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Mon, 05 Oct 2026 22:22:49 +0000</pubDate>

</item> 
<item>
	<title>Steinar H. Gunderson: Decompilation patterns part 2: do-while</title>
	<guid>http://blog.sesse.net/blog/tech/2026-10-05-16-54_decompilation_patterns_part_2_do_while.html</guid>
	<link>http://blog.sesse.net/blog/tech/2026-10-05-16-54_decompilation_patterns_part_2_do_while.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/sesse.png&quot; width=&quot;74&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Continuing our journey on decompilation patterns, here&#39;s another common one:
Let&#39;s say m2c outputs code like this:&lt;/p&gt;

&lt;pre&gt;loop_151:
  ...
  if (var_s0 &amp;gt; var_s1) goto loop_151;
&lt;/pre&gt;

&lt;p&gt;then the natural change is:&lt;/p&gt;

&lt;pre&gt;do {
  ...
} while (var_s0 &amp;gt; var_s1);
&lt;/pre&gt;

&lt;p&gt;Fewer gotos are nearly always good, and this is a much more likely pattern
than the original one.&lt;/p&gt;

&lt;p&gt;m2c often manages to convert gotos to do/while, but not always when they are
e.g. nested in some other loop; so often, you may need to apply some other
transformation before you get to this point.&lt;/p&gt;

&lt;p&gt;Tomorrow, we&#39;ll look at another variation over this topic.&lt;/p&gt; </description> 
	<pubDate>Mon, 05 Oct 2026 15:54:00 +0000</pubDate>

</item> 
<item>
	<title>Vincent Bernat: Hacking the Go compiler to efficiently map IPv4 to IPv6</title>
	<guid>http://www.luffy.cx/en/blog/2026-go-netip-addrto6.html</guid>
	<link>https://vincent.bernat.ch/en/blog/2026-go-netip-addrto6</link>
     <description>  &lt;p&gt;&lt;a href=&quot;https://pkg.go.dev/netip.addr&quot; title=&quot;netip.addr on Go Packages&quot;&gt;&lt;code&gt;netip.Addr&lt;/code&gt;&lt;/a&gt; features an &lt;a href=&quot;https://pkg.go.dev/netip.addr.Unmap&quot; title=&quot;netip.addr.Unmap on Go Packages&quot;&gt;&lt;code&gt;Unmap()&lt;/code&gt;&lt;/a&gt;
method returning the unwrapped IPv4 contained in an &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc4291#section-2.5.5.2&quot; title=&quot;RFC 4291: IP Version 6 Addressing Architecture&quot;&gt;IPv4-mapped IPv6
address&lt;/a&gt;: from &lt;code&gt;::ffff:203.0.113.10&lt;/code&gt; or &lt;code&gt;::ffff:cb00:710a&lt;/code&gt;, it returns
&lt;code&gt;203.0.113.10&lt;/code&gt;.&lt;sup id=&quot;fnref:why&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:why&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; There is no &lt;code&gt;Map()&lt;/code&gt; or &lt;code&gt;To6()&lt;/code&gt; method for the reverse
direction. Such a method is trivial to implement, but Go maintainers have
&lt;a href=&quot;https://github.com/golang/go/issues/54365#issuecomment-1570607144&quot; title=&quot;Issue #54365: proposal: net/netip: add netip.Addr.Map&quot;&gt;rejected&lt;/a&gt; it on the grounds that users should write
&lt;code&gt;netip.AddrFrom16(ip.As16())&lt;/code&gt; and let the compiler optimize it.&lt;sup id=&quot;fnref:equiv&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:equiv&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Today,
this pattern is eight times slower than a native method. How can we teach the
compiler to optimize this sequence?&lt;/p&gt;
&lt;div class=&quot;toc&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#the-alternatives&quot;&gt;The alternatives&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#modifying-the-go-standard-library&quot;&gt;Modifying the Go standard library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#as-a-helper&quot;&gt;As a helper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#as-an-unsafe-function&quot;&gt;As an unsafe function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#benchmarks&quot;&gt;Benchmarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#assembly-code&quot;&gt;Assembly code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#hacking-the-go-compiler&quot;&gt;Hacking the Go compiler&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#the-hammer&quot;&gt;The hammer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#the-screwdriver&quot;&gt;The screwdriver&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#on-paper&quot;&gt;On paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#in-practice&quot;&gt;In practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#out-of-order&quot;&gt;Out of order&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#back-in-order&quot;&gt;Back in order&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#next-steps&quot;&gt;Next steps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;the-alternatives&quot;&gt;The alternatives&lt;/h1&gt;
&lt;p&gt;Letâ€™s explore three ways to implement the map semantics for &lt;code&gt;netip.Addr&lt;/code&gt;. My
favorite is to add it to the Go standard library. Go maintainers prefer a small
external helper chaining &lt;code&gt;netip.AddrFrom16()&lt;/code&gt; and &lt;code&gt;netip.Addr.As16()&lt;/code&gt;, hoping
the compiler eventually optimizes it. The &lt;a href=&quot;https://pkg.go.dev/unsafe&quot; title=&quot;unsafe on Go Packages&quot;&gt;&lt;code&gt;unsafe&lt;/code&gt; package&lt;/a&gt;
opens a third path, with the same performance as the first solution.&lt;/p&gt;
&lt;h2 id=&quot;modifying-the-go-standard-library&quot;&gt;Modifying the Go standard library&lt;/h2&gt;
&lt;p&gt;Internally, &lt;a href=&quot;https://pkg.go.dev/net/netip#Addr&quot; title=&quot;net/netip.Addr on Go Packages&quot;&gt;&lt;code&gt;netip.Addr&lt;/code&gt;&lt;/a&gt; stores any IP address as a
128-bit value with an extra field &lt;code&gt;z&lt;/code&gt; to encode the family and the zone:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uint128&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrDetail&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isV6&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// IPv4 is false, IPv6 is true.&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;zoneV6&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// != &quot;&quot; only if IsV6 is true.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isV6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://pkg.go.dev/net/netip#AddrFrom4&quot; title=&quot;net/netip.AddrFrom4 on Go Packages&quot;&gt;&lt;code&gt;AddrFrom4()&lt;/code&gt;&lt;/a&gt; encodes an IPv4 address as an
IPv4-mapped IPv6 address and sets &lt;code&gt;z&lt;/code&gt; to the unique value &lt;code&gt;z4&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AddrFrom4 returns the address of the IPv4 address given by the bytes in addr.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrFrom4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uint128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xffff00000000&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])},&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://pkg.go.dev/net/netip#Addr.Unmap&quot; title=&quot;net/netip.Addr.Unmap on Go Packages&quot;&gt;&lt;code&gt;Unmap()&lt;/code&gt;&lt;/a&gt; turns an IPv4-mapped IPv6 address into an
IPv4 address by setting the &lt;code&gt;z&lt;/code&gt; field to &lt;code&gt;z4&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Unmap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Is4In6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z4&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Implementing the reverse direction inside the Go standard library is trivial: we
set the &lt;code&gt;z&lt;/code&gt; field to &lt;code&gt;z6noz&lt;/code&gt; if the address is IPv4.&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// To6 maps an IPv4 address to an IPv4-mapped IPv6 address. It returns an&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// IPv6 address unmodified.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;To6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Is4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;admonition&quot;&gt;
&lt;p class=&quot;admonition-title&quot;&gt;Update (2026-10)&lt;/p&gt;
&lt;p&gt;Instead of patching Go, we can use the &lt;a href=&quot;https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies&quot; title=&quot;go build documentation&quot;&gt;&lt;code&gt;-overlay&lt;/code&gt;
flag&lt;/a&gt; of &lt;code&gt;go build&lt;/code&gt; to hijack any package, including the standard
library. In our case, it can &lt;a href=&quot;https://github.com/vincentbernat/go-netip-addrto6/commit/dcc2e1af2af48301d8e992db22d97682bda37b8c&quot; title=&quot;Add an alternative using an overlay&quot;&gt;add &lt;code&gt;To6()&lt;/code&gt; to &lt;code&gt;net/netip&lt;/code&gt;&lt;/a&gt;. Yet
it is cumbersome:&lt;sup id=&quot;fnref:inconvenient&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:inconvenient&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; the flag expects a JSON file mapping absolute
paths in &lt;code&gt;GOROOT&lt;/code&gt; to replacement files, and you need to add it to every &lt;code&gt;go&lt;/code&gt;
command.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;as-a-helper&quot;&gt;As a helper&lt;/h2&gt;
&lt;p&gt;We canâ€™t access the &lt;code&gt;z&lt;/code&gt; field from outside the &lt;code&gt;net/netip&lt;/code&gt; package. Instead, we
build a small helper around the &lt;code&gt;netip.AddrFrom16(ip.As16())&lt;/code&gt; pattern:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AddrTo6 maps an IPv4 address to an IPv4-mapped IPv6 address. It returns an&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// IPv6 address unmodified.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrTo6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Is4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrFrom16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;As16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;as-an-unsafe-function&quot;&gt;As an unsafe function&lt;/h2&gt;
&lt;p&gt;Another solution uses the &lt;code&gt;unsafe&lt;/code&gt; package to alter the &lt;code&gt;Addr&lt;/code&gt; struct through
a proxy with the same memory layout:&lt;sup id=&quot;fnref:tests&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:tests&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// addrProxy has the same memory layout as netip.Addr.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrProxy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// netip.uint128&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// unique.Handle[netip.addrDetail]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;anyIPv6&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;IPv6Unspecified&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netipZ6noz&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;anyIPv6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// AddrTo6 maps an IPv4 address to an IPv4-mapped IPv6 address. It returns an&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// IPv6 address unmodified.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrTo6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Is4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addrProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netipZ6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;benchmarks&quot;&gt;Benchmarks&lt;/h2&gt;
&lt;p&gt;On my computer, with Goâ€¯1.27.1, the standard library solution costs 0.88 ns per
operation, while the solution favored by Go maintainers costs 7.14 ns. The
unsafe solution matches the performance of the first one.&lt;/p&gt;
&lt;div class=&quot;language-text-only codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;goos: linux
goarch: amd64
pkg: github.com/vincentbernat/go-netip-addrto6
cpu: AMD Ryzen 5 5600X 6-Core Processor
                   â”‚     sec/op     â”‚
AddrTo6/safe            7.137n Â± 0%
AddrTo6/unsafe         0.8682n Â± 2%
AddrTo6/builtin        0.8775n Â± 2%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;assembly-code&quot;&gt;Assembly code&lt;/h2&gt;
&lt;p&gt;Letâ€™s check the assembly code the compiler generates for each solution.&lt;sup id=&quot;fnref:dis&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:dis&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
The one built into the standard library looks like this:&lt;sup id=&quot;fnref:inline&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:inline&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-go-assembly codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AX = input.addr.hi, BX = input.addr.lo, CX = input.z&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CMPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; check &quot;z&quot; if this is an IPv4 address&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;JNE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; if not, stop here&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; CX = netip.z6noz&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RET&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return value = Addr{hi: AX, lo: BX, z: CX}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Goâ€™s &lt;a href=&quot;https://go.dev/doc/asm&quot; title=&quot;A Quick Guide to Go&#39;s Assembler&quot;&gt;assembly language&lt;/a&gt; is not a direct representation of the underlying
machine language: it operates on a semi-abstract instruction set derived from
&lt;a href=&quot;https://9p.io/sys/doc/asm.html&quot; title=&quot; A Manual for the Plan 9 assembler&quot;&gt;Planâ€¯9â€™s assembler&lt;/a&gt;. It has four pseudo-registers: FP (frame pointer
for function arguments), PC (program counter), SB (static base pointer for
global symbols), and SP (stack pointer). It also has architecture-specific
registers like &lt;code&gt;AX&lt;/code&gt;, &lt;code&gt;CX&lt;/code&gt;, &lt;code&gt;DX&lt;/code&gt;, &lt;code&gt;BX&lt;/code&gt;, &lt;code&gt;SI&lt;/code&gt;, &lt;code&gt;DI&lt;/code&gt;, and &lt;code&gt;R8&lt;/code&gt; to &lt;code&gt;R15&lt;/code&gt;.
Instructions storing data use their last argument as the destination.
Instructions can carry an explicit size suffix: &lt;code&gt;MOVB&lt;/code&gt; moves a byte, &lt;code&gt;MOVW&lt;/code&gt;â€¯16
bits, &lt;code&gt;MOVL&lt;/code&gt;â€¯32 bits, and &lt;code&gt;MOVQ&lt;/code&gt;â€¯64 bits. In the example above, the first
instruction compares the 64-bit value &lt;code&gt;z4&lt;/code&gt; with the &lt;code&gt;CX&lt;/code&gt; register.&lt;/p&gt;
&lt;p&gt;The unsafe solution looks almost the same:&lt;/p&gt;
&lt;div class=&quot;language-go-assembly codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AX = input.addr.hi, BX = input.addr.lo, CX = input.z&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CMPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; check &quot;z&quot; if this is an IPv4 address&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;JNE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; if not, stop here&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;netipZ6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; CX = netip.z6noz&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RET&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return value = Addr{hi: AX, lo: BX, z: CX}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The helper solution has far more instructions. To understand why, letâ€™s look at
the code for &lt;a href=&quot;https://pkg.go.dev/netip.addr.As16&quot; title=&quot;netip.addr.As16 on Go Packages&quot;&gt;&lt;code&gt;As16()&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;https://pkg.go.dev/netip.AddrFrom16&quot; title=&quot;netip.AddrFrom16 on Go Packages&quot;&gt;&lt;code&gt;AddrFrom16()&lt;/code&gt;&lt;/a&gt;. They are short enough for the compiler
to inline them.&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;As16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEPutUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEPutUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrFrom16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uint128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]),&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can already guess the pattern to optimize: the code packs the IP address into
an array, copies it, then unpacks it. If we inline the Go code by hand, we get:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrTo6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Is4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEPutUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEPutUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a16&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hi&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteorder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As humans, we can mentally derive the optimized form:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddrTo6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Is4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hi&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;netip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p id=&quot;asm-addrto6safe&quot;&gt;Unfortunately, as of Goâ€¯1.26.8, the compiler is not smart enough to do the same:&lt;/p&gt;
&lt;div class=&quot;language-go-assembly codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AX = input.addr.hi, BX = input.addr.lo, CX = input.z&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; Push the stack (32 bytes):&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;    0(SP) addr netip.uint128&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;   16(SP) a16 [16]byte&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PUSHQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BP&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BP&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SUBQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CMPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; check &quot;z&quot; if this is an IPv4 address&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;JNE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; if not, stop here&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; Pack: byteorder.BEPutUint64(a16[:8], input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;       byteorder.BEPutUint64(a16[8:], input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; addr = a16, 16 bytes at once through the vector register X0&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVUPS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;X0&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVUPS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;X0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; CX = netip.z6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; Unpack: output.addr.hi = byteorder.BEUint64(addr[:8])&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;         output.addr.lo = byteorder.BEUint64(addr[8:])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ADDQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;POPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BP&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RET&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return value = Addr{hi: AX, lo: BX, z: CX}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The compiler does a decent job on the byte shuffling: the eight byte stores of
&lt;code&gt;BEPutUint64()&lt;/code&gt; become a single &lt;code&gt;MOVBEQ&lt;/code&gt;, which stores a register byte-swapped.
The eight byte loads of &lt;code&gt;BEUint64()&lt;/code&gt; become a single &lt;code&gt;MOVBEQ&lt;/code&gt; the other way
round.&lt;sup id=&quot;fnref:amd64v3&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:amd64v3&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; Three groups of instructions remain: a pack, a copy, and an
unpack.&lt;/p&gt;
&lt;h1 id=&quot;hacking-the-go-compiler&quot;&gt;Hacking the Go compiler&lt;/h1&gt;
&lt;p&gt;The Go compiler has &lt;a href=&quot;https://github.com/golang/go/blob/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/README.md&quot; title=&quot;Introduction to the Go compiler&quot;&gt;several phases&lt;/a&gt;:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Parsing&lt;/dt&gt;
&lt;dd&gt;The compiler &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/syntax&quot; title=&quot;cmd/compile/internal/syntax&quot;&gt;tokenizes and parses the source code&lt;/a&gt;. It builds a syntax tree
  for each source file.&lt;/dd&gt;
&lt;dt&gt;Type checking&lt;/dt&gt;
&lt;dd&gt;The compiler &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/types2&quot; title=&quot;cmd/compile/internal/types2&quot;&gt;maps each identifier to the object it denotes&lt;/a&gt;, folds
  constants, and infers the type of every expression.&lt;/dd&gt;
&lt;dt&gt;&lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt; construction&lt;/dt&gt;
&lt;dd&gt;The compiler converts the syntax tree and its types into its own &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ir&quot; title=&quot;cmd/compile/internal/ir&quot;&gt;intermediate
  representation&lt;/a&gt; (&lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt;). This process, called â€œ&lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/noder&quot; title=&quot;cmd/compile/internal/noder&quot;&gt;noding&lt;/a&gt;,â€� goes through
  a serialization format named unified &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt;.&lt;/dd&gt;
&lt;dt&gt;Middle end&lt;/dt&gt;
&lt;dd&gt;The compiler performs several optimization passes on the &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt;,
  such as &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/devirtualize&quot; title=&quot;cmd/compile/internal/devirtualize&quot;&gt;devirtualization&lt;/a&gt;, &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/inline&quot; title=&quot;cmd/compile/internal/inline&quot;&gt;function call inlining&lt;/a&gt;,
  and &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/escape&quot; title=&quot;cmd/compile/internal/escape&quot;&gt;escape analysis&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;Walk&lt;/dt&gt;
&lt;dd&gt;This phase runs &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/walk&quot; title=&quot;cmd/compile/internal/walk&quot;&gt;two steps&lt;/a&gt;: order of evaluation decomposes complex
  statements into simpler ones, and desugaring transforms higher-level Go
  constructs, like &lt;code&gt;switch&lt;/code&gt; or channels, into more primitive instructions or
  calls to the runtime.&lt;/dd&gt;
&lt;dt&gt;Generic &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt;&lt;/dt&gt;
&lt;dd&gt;The compiler &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssagen&quot; title=&quot;cmd/compile/internal/ssagen&quot;&gt;converts the &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt;&lt;/a&gt; into Static Single Assignment (&lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt;)
  form, a lower-level intermediate representation suited for
  &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssa&quot; title=&quot;cmd/compile/internal/ssa&quot;&gt;machine-independent optimizations and rewrite rules&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;Machine code generation&lt;/dt&gt;
&lt;dd&gt;The compiler rewrites the &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; form into &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssa/_gen&quot; title=&quot;cmd/compile/internal/ssa/_gen&quot;&gt;machine-specific variants&lt;/a&gt;,
  allocates registers, and applies more optimization passes. At the end, &lt;a href=&quot;https://github.com/golang/go/tree/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/internal/obj&quot; title=&quot;cmd/internal/obj&quot;&gt;the
  assembler&lt;/a&gt; turns the generated instructions into machine code.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&quot;the-hammer&quot;&gt;The hammer&lt;/h2&gt;
&lt;p&gt;My first idea is to replace occurrences of &lt;code&gt;netip.AddrFrom16(ip.As16())&lt;/code&gt; with
&lt;code&gt;netip.Addr{addr: ip.addr, z: netip.z6noz}&lt;/code&gt; as early as possible, during the
â€œnodingâ€� process. Before that, the type checking phase prevents
us from accessing unexported struct fields.&lt;/p&gt;
&lt;p&gt;Goâ€¯1.27 introduced a convenient debug option to dump the &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt; of a function at
interesting points during compilation:&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOTOOLCHAIN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;go1.27.1&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOAMD64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;v3&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;go&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;build&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-a&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-gcflags&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-d=astdump=AddrTo6Safe&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.
&lt;span class=&quot;go&quot;&gt;Writing text ast output for AddrTo6Safe to AddrTo6Safe.ast&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Writing html ast output for AddrTo6Safe to AddrTo6Safe.html&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Writing html syntax output for AddrTo6Safe to AddrTo6Safe.syntax.html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the HTML file, the first column shows the &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt; as it comes out of noding:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ir codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;DCLFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;addrto6.AddrTo6Safe&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ABI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ABIInternal&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FUNC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;func(netip.Addr)&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;k&quot;&gt;DCLFUNC-Dcl&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.~r0&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAMOUT&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;k&quot;&gt;DCLFUNC-body&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;IF&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# ipv6_safe.go:11:2&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;IF-Cond&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bool
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC-Fun&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;METHEXPR&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;addrto6.Is4&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FUNC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;func(netip.Addr)&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bool
&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PEXTERN&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;type&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC-Args&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;IF-Body&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# ipv6_safe.go:12:6&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC-Fun&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;netip.AddrFrom16&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FUNC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;func([&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;]byte)&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC-Args&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ARRAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;[&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;]byte
&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC-Fun&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;. . . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;METHEXPR&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;addrto6.As16&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FUNC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;func(netip.Addr)&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;[&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;]byte
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;. . . . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PEXTERN&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;type&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;CALLFUNC-Args&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;RETURN&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# ipv6_safe.go:14:2&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;RETURN-Results&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the body of the &lt;code&gt;if&lt;/code&gt; statement, we spot the calls to the method
&lt;code&gt;netip.Addr.As16()&lt;/code&gt; and to the function &lt;code&gt;netip.AddrFrom16()&lt;/code&gt;. Our goal is to
patch them with a struct literal:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ir codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;IF-Body&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# ipv6_safe.go:12:6&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;STRUCTLIT&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;STRUCTLIT-List&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;STRUCTKEY&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.addr
&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;DOT&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.addr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.uint128
&lt;span class=&quot;w&quot;&gt;. . . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;addrto6.ip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PPARAM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnStack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Used&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.Addr
&lt;span class=&quot;w&quot;&gt;. . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;STRUCTKEY&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;netip.z
&lt;span class=&quot;w&quot;&gt;. . . . &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;netip.z6noz&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PEXTERN&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;unique.Handle[net/netip.addrDetail]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In &lt;a href=&quot;https://github.com/golang/go/blob/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/noder/reader.go&quot; title=&quot;reader.go&quot;&gt;noderâ€™s &lt;code&gt;reader.go&lt;/code&gt;&lt;/a&gt;, the &lt;code&gt;expr()&lt;/code&gt; method builds the &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt; tree for
an expression. At the end of the &lt;code&gt;exprCall&lt;/code&gt; case, we add a call to a
&lt;code&gt;rewriteAddrFrom16As16()&lt;/code&gt; function. It takes the current node and returns the
struct literal on success, or &lt;code&gt;nil&lt;/code&gt; if the rewrite is not possible. First, we
check that we have the expected pattern: a call to the &lt;code&gt;netip.AddrFrom16()&lt;/code&gt;
function with a call to the &lt;code&gt;netip.Addr.As16()&lt;/code&gt; method as its only argument:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rewriteAddrFrom16As16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CallExpr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OCALLFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isNetipFunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;AddrFrom16&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CallExpr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OCALLFUNC&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isNetipFunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Addr.As16&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// [...]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, we fetch &lt;code&gt;netip.z6noz&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lookupVar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;StaticCalleeName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Pkg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;z6noz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And we build the struct literal:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;typ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Node&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;typ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Node&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;addr&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;typecheck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DotField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;z&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NewStructKeyExpr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;lit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NewCompLitExpr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OSTRUCTLIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;typ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;lit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SetTypecheck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Have a look at the &lt;a href=&quot;https://github.com/vincentbernat/go/commit/netipmap-fix2&quot; title=&quot;cmd/compile: optimize netip.AddrFrom16(ip.As16()) in the noder&quot;&gt;complete patch&lt;/a&gt;.&lt;sup id=&quot;fnref:statement&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:statement&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; We can test it
with the following commands:&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;src
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;./make.bash
&lt;span class=&quot;go&quot;&gt;Building Go cmd/dist using /usr/lib/go-1.27. (go1.27.1 linux/amd64)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Building Go toolchain1 and bootstrap cmd/go (go_bootstrap) using /usr/lib/go-1.27.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Building Go toolchain2 using go_bootstrap and Go toolchain1.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Building Go toolchain3 and commands using go_bootstrap and Go toolchain2.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Checking command staleness for linux/amd64.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Installed Go for linux/amd64 in /home/bernat/code/free/go&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Installed commands in /home/bernat/code/free/go/bin&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;*** You need to add /home/bernat/code/free/go/bin to your PATH.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PWD&lt;/span&gt;/../bin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;go&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;version
&lt;span class=&quot;go&quot;&gt;go version go1.28-devel_9834516e20 Sat Sep 12 08:23:11 2026 -0700 linux/amd64&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;go&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;net/netip/...
&lt;span class=&quot;go&quot;&gt;ok      net/netip   0.224s&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;../../go-netip-addrto6
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;go&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.
&lt;span class=&quot;go&quot;&gt;ok      github.com/vincentbernat/go-netip-addrto6   0.062s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The generated code for the helper is now the shortest possible version!&lt;/p&gt;
&lt;div class=&quot;language-go-assembly codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AX = input.addr.hi, BX = input.addr.lo, CX = input.z&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CMPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; check &quot;z&quot; if this is an IPv4 address&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;JNE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; if not, stop here&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; CX = netip.z6noz&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RET&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return value = Addr{hi: AX, lo: BX, z: CX}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Go maintainers are unlikely to accept this change. It relies on the internal
structure of &lt;code&gt;net/netip.Addr&lt;/code&gt;. Itâ€™s an ugly hack in the noder, whose job is to
faithfully translate the type-checked AST into the &lt;abbr title=&quot;Intermediate Representation&quot;&gt;IR&lt;/abbr&gt;. And itâ€™s harder to
maintain than adding a &lt;code&gt;To6()&lt;/code&gt; method.&lt;/p&gt;
&lt;h2 id=&quot;the-screwdriver&quot;&gt;The screwdriver&lt;/h2&gt;
&lt;p&gt;The right place for such an optimization is the &lt;a href=&quot;https://github.com/golang/go/blob/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssa/README.md&quot; title=&quot;Introduction to the Go compiler&#39;s SSA backend&quot;&gt;generic &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; phase&lt;/a&gt;. One of
the last machine-independent passes is &lt;code&gt;memcombine&lt;/code&gt;. With the appropriate debug
flag, the compiler dumps the &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; form after this pass:&lt;sup id=&quot;fnref:html&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:html&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOTOOLCHAIN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;go1.26.8&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOAMD64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;v3&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;go&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;build&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-a&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-gcflags&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;-d=ssa/memcombine/dump=AddrTo6Safe&#39;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;head&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-5&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;AddrTo6Safe_01__memcombine.dump
&lt;span class=&quot;go&quot;&gt;AddrTo6Safe func(netip.Addr) netip.Addr&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  b2:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    (?) v1 = InitMem &amp;lt;mem&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    (?) v2 = SP &amp;lt;uintptr&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    (?) v3 = SB &amp;lt;uintptr&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result of the &lt;code&gt;memcombine&lt;/code&gt; pass follows the same structure as the assembly
code for &lt;code&gt;AddrTo6Safe()&lt;/code&gt; &lt;a href=&quot;https://vincent.bernat.ch#asm-addrto6safe&quot;&gt;we looked at earlier&lt;/a&gt;: two stores,
one move, and two loads we would like to optimize away.&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;; [â€¦]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+0}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+8}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v466&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*netip.addrDetail&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[2]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.z&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; [â€¦]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v23&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8] = bswap(hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[:8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v299&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[8:]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; [â€¦]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Each line features a value identifier (&lt;code&gt;v442&lt;/code&gt;), an operation with its type
(&lt;code&gt;Bswap64 &amp;lt;uint64&amp;gt;&lt;/code&gt;), and its arguments (&lt;code&gt;v490&lt;/code&gt;).&lt;sup id=&quot;fnref:lines&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:lines&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; Values are the basic
building blocks of &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; and are defined exactly once. Square brackets enclose
integer parameters (&lt;code&gt;[8]&lt;/code&gt;) and curly braces contain auxiliary arguments
(&lt;code&gt;{netip.addr}&lt;/code&gt;). Operations writing to memory produce a new memory state. Every
memory operation takes the current state as its last argument, which keeps them
in order.&lt;/p&gt;
&lt;h3 id=&quot;on-paper&quot;&gt;On paper&lt;/h3&gt;
&lt;p&gt;Letâ€™s focus on &lt;code&gt;output.addr.lo&lt;/code&gt;, aka &lt;code&gt;v39&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+8}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[8:]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To simplify this code, we could apply three rewriting rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The first one adds a shortcut when &lt;strong&gt;loading through a move&lt;/strong&gt;: &lt;code&gt;(Load (OffPtr
   [o] p) (Move p src mem)) =&amp;gt; (Load (OffPtr [o] src) mem)&lt;/code&gt;. This matches &lt;code&gt;v174&lt;/code&gt;
   with its arguments &lt;code&gt;v415&lt;/code&gt; and &lt;code&gt;v286&lt;/code&gt; and creates a new value &lt;code&gt;v600&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+8}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[8]&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v600&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v600&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The second one simplifies a &lt;strong&gt;load following a store&lt;/strong&gt;: &lt;code&gt;(Load p (Store p x
   _)) =&amp;gt; x&lt;/code&gt;. The load is &lt;em&gt;forwarded&lt;/em&gt;: the stored value replaces it and no memory
   access remains. It matches &lt;code&gt;v174&lt;/code&gt;. It notices that &lt;code&gt;v600&lt;/code&gt; and &lt;code&gt;v173&lt;/code&gt; are the
   same address and replaces &lt;code&gt;v174&lt;/code&gt; with a copy of &lt;code&gt;v442&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+8}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v600&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The last step &lt;strong&gt;cancels the two byte swaps&lt;/strong&gt;: &lt;code&gt;(Bswap64 (Bswap64 x)) =&amp;gt; x&lt;/code&gt;.
   &lt;code&gt;v39&lt;/code&gt; becomes a copy of &lt;code&gt;v490&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+8}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v415&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v600&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v174&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo = input.addr.lo&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we ignore the values not needed to compute &lt;code&gt;v39&lt;/code&gt;, only this &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; form remains:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+8}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;             &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo = input.addr.lo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Letâ€™s switch to &lt;code&gt;output.addr.hi&lt;/code&gt;, aka &lt;code&gt;v299&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+0}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v23&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8] = bswap(hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[:8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v299&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To optimize it away, we also apply three rewriting rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The first one also adds a shortcut when &lt;strong&gt;loading through a move&lt;/strong&gt;, but
   without an offset: &lt;code&gt;(Load p (Move p src mem)) =&amp;gt; (Load src mem)&lt;/code&gt;. This rewrites &lt;code&gt;v416&lt;/code&gt;
   to use arguments from &lt;code&gt;v286&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+0}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v23&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8] = bswap(hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v299&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The second rule &lt;strong&gt;forwards a value stored one step earlier&lt;/strong&gt;, skipping over a
   store to another address: &lt;code&gt;(Load p (Store q _ (Store p x _))) =&amp;gt; x&lt;/code&gt;. This
   matches &lt;code&gt;v416&lt;/code&gt;: &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;v542&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt; is &lt;code&gt;v22&lt;/code&gt; (&lt;code&gt;&amp;amp;a16&lt;/code&gt;), &lt;code&gt;q&lt;/code&gt; is &lt;code&gt;v173&lt;/code&gt;
   (&lt;code&gt;&amp;amp;a16[8]&lt;/code&gt;), and &lt;code&gt;p&lt;/code&gt; and &lt;code&gt;q&lt;/code&gt; do not overlap for &lt;code&gt;uint64&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+0}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v23&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8] = bswap(hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v299&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The third rule &lt;strong&gt;cancels two byte swaps&lt;/strong&gt;: &lt;code&gt;(Bswap64 (Bswap64 x)) =&amp;gt; x&lt;/code&gt;.
   &lt;code&gt;v299&lt;/code&gt; becomes a copy of &lt;code&gt;v502&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+0}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.a16}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[8]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v23&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8] = bswap(hi)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{uint64}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v173&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v442&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v161&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8:] = bswap(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v416&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v542&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; bswap(input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v299&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi = input.addr.hi&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we remove the values not used to compute &lt;code&gt;v299&lt;/code&gt;, we get this &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; form:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ArgIntReg&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{ip+0}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; input.addr.hi&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v299&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v502&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi = input.addr.hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;in-practice&quot;&gt;In practice&lt;/h3&gt;
&lt;p&gt;Most of these rules already exist in &lt;a href=&quot;https://github.com/golang/go/blob/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssa/_gen/generic.rules&quot; title=&quot;generic.rules&quot;&gt;&lt;code&gt;generic.rules&lt;/code&gt;&lt;/a&gt;. They use
conditions to validate their context: &lt;code&gt;ssa.IsSamePtr()&lt;/code&gt; for the same address,
&lt;code&gt;ssa.Disjoint()&lt;/code&gt; for addresses that do not overlap. The rule forwarding a stored
value to a load already exists with three variants looking through several other
stores. Here are the two we need:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa-rules codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;t1&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p1&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{t2}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;x&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;_&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.IsSamePtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;p1,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;copyCompatibleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;t1,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;x.Type&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;t1.Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;t2.Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;x
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;t1&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p1&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{t2}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;_&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{t3}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p3&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;x&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;_&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.IsSamePtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;p1,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p3&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;copyCompatibleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;t1,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;x.Type&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;t1.Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;t3.Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.Disjoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;p3,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;t3,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;t2&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Goâ€¯1.27 added the rule loading through a move with &lt;a href=&quot;https://go-review.googlesource.com/c/go/+/748200&quot; title=&quot;cmd/compile: forward small Load through Move to avoid redundant copies&quot;&gt;CLâ€¯748200&lt;/a&gt; to fix
&lt;a href=&quot;https://github.com/golang/go/issues/77720&quot; title=&quot;cmd/compile: field access on struct-returning method copies entire struct&quot;&gt;issueÂ #77720&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa-rules codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;t1&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;op1:&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[o1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;move:&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[n]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;src&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mem&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;o1&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;o1&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;t1.Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;n&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.IsSamePtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;p1,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.IsVolatile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;src&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@move.Block&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;t1&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;op1.Type&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[o1]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;src&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mem&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It lacks a variant without an offset:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa-rules codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;t1&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p1&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;move:&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[n]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;src&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mem&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p1.Op&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;ssaop.OpOffPtr
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;t1.Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;n&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.IsSamePtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;p1,&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p2&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ssa.IsVolatile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;src&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@move.Block&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;t1&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;p1.Type&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;src&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mem&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is no generic rule to cancel two byte swaps, but the &lt;a href=&quot;https://github.com/golang/go/blob/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssa/_gen/AMD64.rules&quot; title=&quot;AMD64.rules&quot;&gt;AMD64 lowering
pass&lt;/a&gt; includes this rule:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa-rules codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;BSWAP(Q|L)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;BSWAP(Q|L)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After switching to Goâ€™s development branch and &lt;a href=&quot;https://github.com/vincentbernat/go/commit/netipmap-fix3&quot; title=&quot;cmd/compile/internal/ssa: forward small offset-less Load through Move&quot;&gt;adding the missing
rule&lt;/a&gt;, the generated assembly code is worse than with Goâ€¯1.26.8,
even though our additional rule slightly improves the situation at the end:&lt;/p&gt;
&lt;div class=&quot;language-go-assembly codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AX = input.addr.hi, BX = input.addr.lo, CX = input.z&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; Push the stack (16 bytes):&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;    0(SP) a16 [16]byte&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PUSHQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BP&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BP&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SUBQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CMPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;       &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; check &quot;z&quot; if this is an IPv4 address&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;JNE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; if not, stop here&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; The four forwarded bytes: the low half of input.addr.lo is taken apart and&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; put back together in registers&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; DX = input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHRQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; BX = input.addr.lo &amp;gt;&amp;gt; 24&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; SI = input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHRQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; DX = input.addr.lo &amp;gt;&amp;gt; 16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; DI = input.addr.lo, kept for the pack&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHRQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; SI = input.addr.lo &amp;gt;&amp;gt; 8&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;DIB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; R8 = byte(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;SIB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; SI = byte(input.addr.lo &amp;gt;&amp;gt; 8)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; SI = two low bytes of input.addr.lo&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; DX = byte(input.addr.lo &amp;gt;&amp;gt; 16)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; BX = byte(input.addr.lo &amp;gt;&amp;gt; 24)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; BX = input.addr.lo &amp;amp; 0xffffffff&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; Pack: byteorder.BEPutUint64(a16[:8], input.addr.hi)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;       byteorder.BEPutUint64(a16[8:], input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; The four other bytes of input.addr.lo, read one by one from a16&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[11]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[10]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[9]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBLZX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SHLQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;; output.z = netip.z6noz&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; output.addr.hi = byteorder.BEUint64(a16[:8])&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVBEQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·a16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AX&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.lo assembled from the previous steps&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ORQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BX&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;LEAVEQ&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RET&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return value = Addr{hi: AX, lo: BX, z: CX}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The rule loading through a move, added in Goâ€¯1.27, introduced this regression.&lt;/p&gt;
&lt;h3 id=&quot;out-of-order&quot;&gt;Out of order&lt;/h3&gt;
&lt;p&gt;Letâ€™s not give up now! In reality, the rewriting rules run before &lt;code&gt;memcombine&lt;/code&gt;,
notably in the &lt;code&gt;late opt&lt;/code&gt; pass. At this point, the inlined versions of
&lt;code&gt;BEPutUint64()&lt;/code&gt; and &lt;code&gt;BEUint64()&lt;/code&gt; still expand to sixteen byte stores and sixteen
byte loads, matching their &lt;a href=&quot;https://pkg.go.dev/internal/byteorder#BEUint64&quot; title=&quot;internal/byteorder.BEUint64 on Go Packages&quot;&gt;source code&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BEUint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// bounds check hint to compiler; see golang.org/issue/14808&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Letâ€™s follow two bytes of &lt;code&gt;output.addr.lo&lt;/code&gt;: &lt;code&gt;addr[15]&lt;/code&gt; and &lt;code&gt;addr[11]&lt;/code&gt;. Here is
a simplified &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; form before &lt;code&gt;late opt&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v273&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Trunc64to8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v490&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; byte(input.addr.lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v226&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Trunc64to8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v225&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; byte(input.addr.lo &amp;gt;&amp;gt; 32)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; [â€¦]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v235&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v233&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v226&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v223&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[11] = byte(lo &amp;gt;&amp;gt; 32)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v247&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v245&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v238&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v235&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[12] = â€¦&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v259&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v257&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v250&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v247&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[13] = â€¦&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v271&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v269&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v262&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v259&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[14] = â€¦&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v280&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v273&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v271&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[15] = byte(lo)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;LocalAddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*[16]byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{netip.addr}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Move&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;mem&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;{[16]byte}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[16]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr = a16&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; [â€¦]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v433&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[15]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[15]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v435&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v433&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[15]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v479&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[11]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;addr[11]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v481&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v479&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[11]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first rule loads through the move: &lt;code&gt;(Load (OffPtr [o] p) (Move p src mem))
=&amp;gt; (Load (OffPtr [o] src) mem)&lt;/code&gt;. It matches both loads, which now read &lt;code&gt;a16&lt;/code&gt;
with the memory state before the copy:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v600&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[15]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[15]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v435&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v600&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[15]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v601&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[11]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[11]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v481&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v601&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[11]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The second rule shortcuts a load following a store: &lt;code&gt;(Load p (Store p x _)) =&amp;gt;
x&lt;/code&gt;. It matches &lt;code&gt;v435&lt;/code&gt;, as &lt;code&gt;v282&lt;/code&gt; stores &lt;code&gt;a16[15]&lt;/code&gt;. It does not match &lt;code&gt;v481&lt;/code&gt;:
&lt;code&gt;v235&lt;/code&gt; stores &lt;code&gt;a16[11]&lt;/code&gt; four stores earlier in the chain, while the variants of
this rule look through three stores at most.&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v435&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Copy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v273&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; byte(input.addr.lo)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v601&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;OffPtr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;*byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[11]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; &amp;amp;a16[11]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v481&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v601&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[11]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The same happens to the other bytes: the rule forwards the four bytes stored
last, &lt;code&gt;a16[12]&lt;/code&gt; to &lt;code&gt;a16[15]&lt;/code&gt;. The twelve other loads now read &lt;code&gt;a16&lt;/code&gt; instead of
&lt;code&gt;addr&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;BEUint64()&lt;/code&gt; becomes a chain of &lt;code&gt;Or64&lt;/code&gt;, each one adding a byte shifted into
place. &lt;code&gt;memcombine&lt;/code&gt; is a &lt;a href=&quot;https://github.com/golang/go/blob/1e963f82914ddfb47820034c5c85205a362ed73f/src/cmd/compile/internal/ssacompile/memcombine.go&quot; title=&quot;memcombine.go&quot;&gt;pass written in Go&lt;/a&gt;, not a set of rewrite
rules. It starts from the last &lt;code&gt;Or64&lt;/code&gt; of the chain and collects up to eight
terms. If each term is a byte load, extended to 64 bits and shifted, and if the
eight loads read consecutive addresses from the same pointer with the same
memory state, it replaces the whole chain with a single 64-bit load and a byte
swap. Otherwise, it tries again with four, then two terms, and from each
intermediate &lt;code&gt;Or64&lt;/code&gt;. Here is the loop checking each term in a simplified version
of &lt;code&gt;combineLoads()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Op&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;shiftOp&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;peelShift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Op&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extOp&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Op&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ssaop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OpLoad&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;splitPtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LoadRecord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For &lt;code&gt;output.addr.hi&lt;/code&gt;, the eight loads read &lt;code&gt;a16&lt;/code&gt; with the same memory state
&lt;code&gt;v282&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v13&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;               &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[0]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v530&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v14&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;               &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[1]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v488&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v504&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[2]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v405&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v537&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[3]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v385&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v397&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[4]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v361&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v373&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[5]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v196&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v63&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;               &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[6]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v432&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;byte&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v315&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[7]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v319&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ZeroExt8to64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v432&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; uint64(a16[7])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v329&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ZeroExt8to64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v196&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;         &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; uint64(a16[6])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v330&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Lsh64x64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[true]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v329&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v138&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; uint64(a16[6]) &amp;lt;&amp;lt; 8&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v331&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v319&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v330&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[7] | a16[6] &amp;lt;&amp;lt; 8&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;; [â€¦] same for a16[5] to a16[1]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v401&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ZeroExt8to64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v13&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; uint64(a16[0])&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v402&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Lsh64x64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;[true]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v401&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v55&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; uint64(a16[0]) &amp;lt;&amp;lt; 56&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v403&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v402&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v391&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | a16[0] &amp;lt;&amp;lt; 56 = output.addr.hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;memcombine&lt;/code&gt; merges them into one load and a swap:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v282&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; a16[:8]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v285&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Bswap64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v286&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; output.addr.hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For &lt;code&gt;output.addr.lo&lt;/code&gt;, here is the chain &lt;code&gt;memcombine&lt;/code&gt; sees after &lt;code&gt;late opt&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-go-compiler-ssa codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v436&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ZeroExt8to64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v273&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; addr[15], forwarded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v448&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v436&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v447&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | addr[14] &amp;lt;&amp;lt; 8, forwarded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v460&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v459&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v448&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | addr[13] &amp;lt;&amp;lt; 16, forwarded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v472&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v471&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v460&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | addr[12] &amp;lt;&amp;lt; 24, forwarded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v484&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v483&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v472&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | a16[11] &amp;lt;&amp;lt; 32, loaded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v496&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v495&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v484&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | a16[10] &amp;lt;&amp;lt; 40, loaded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v508&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v507&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v496&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | a16[9] &amp;lt;&amp;lt; 48, loaded&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v520&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Or64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;&amp;lt;uint64&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v519&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;v508&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; | a16[8] &amp;lt;&amp;lt; 56, loaded&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From &lt;code&gt;v520&lt;/code&gt;, four of the eight terms are forwarded bytes, not loads from memory,
and &lt;code&gt;memcombine&lt;/code&gt; canâ€™t combine them. It doesnâ€™t merge the four remaining loads
either, as they sit on top of the forwarded bytes.&lt;/p&gt;
&lt;h3 id=&quot;back-in-order&quot;&gt;Back in order&lt;/h3&gt;
&lt;p&gt;In summary, the rewriting rules run too early to be effective. A quick
workaround exists: run an earlier round of &lt;code&gt;memcombine&lt;/code&gt; before &lt;code&gt;late opt&lt;/code&gt;. After
&lt;a href=&quot;https://github.com/vincentbernat/go/commit/netipmap-fix4&quot; title=&quot;cmd/compile/internal/ssacompile: run memcombine before late opt&quot;&gt;this change&lt;/a&gt;, the generated code for the helper is back to the
shortest possible version:&lt;/p&gt;
&lt;div class=&quot;language-go-assembly codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// AX = input.addr.hi, BX = input.addr.lo, CX = input.z&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CMPQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; check &quot;z&quot; if this is an IPv4 address&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;JNE&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; if not, stop here&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MOVQ&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;net/netipÂ·z6noz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CX&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; CX = netip.z6noz&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RET&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// return value = Addr{hi: AX, lo: BX, z: CX}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And the benchmark confirms it! âœŒï¸�&lt;/p&gt;
&lt;div class=&quot;language-text-only codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;goos: linux
goarch: amd64
pkg: github.com/vincentbernat/go-netip-addrto6
cpu: AMD Ryzen 5 5600X 6-Core Processor
                   â”‚   Go 1.26.8    â”‚             Our branch              â”‚
                   â”‚     sec/op     â”‚    sec/op     vs base               â”‚
AddrTo6/safe          6.5470n Â±  0%   0.8944n Â± 4%  -86.34% (p=0.002 n=6)
AddrTo6/unsafe        0.9071n Â±  3%   0.8682n Â± 1%   -4.28% (p=0.002 n=6)
AddrTo6/builtin       0.8871n Â±  2%   0.8785n Â± 1%        ~ (p=0.310 n=6)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1 id=&quot;next-steps&quot;&gt;Next steps&lt;/h1&gt;
&lt;p&gt;I think Go maintainers would reject this change because of the additional
&lt;code&gt;memcombine&lt;/code&gt; pass. Instead, I plan to publish this blog post and bring up the
subject again as a follow-up to &lt;a href=&quot;https://github.com/golang/go/issues/54365&quot; title=&quot;proposal: net/netip: add netip.Addr.Map Â· Issue #54365 Â· golang/go&quot;&gt;issue #54365&lt;/a&gt;. Either the sheer complexity and
the Goâ€¯1.27 regression convince the maintainers that adding a &lt;code&gt;To6()&lt;/code&gt; method is
simpler and more efficient, or they advise me on how to move forward. Either
way, digging into this subject taught me a lot about the Go compiler! âš™ï¸�&lt;/p&gt;
&lt;div class=&quot;admonition&quot;&gt;
&lt;p class=&quot;admonition-title&quot;&gt;Update (2026-10)&lt;/p&gt;
&lt;p&gt;I opened &lt;a href=&quot;https://github.com/golang/go/issues/81994&quot; title=&quot;proposal: net/netip: add netip.Addr.To6() Â· Issue #81994 Â· golang/go&quot;&gt;issue #81994&lt;/a&gt; to propose &lt;code&gt;Addr.To6()&lt;/code&gt;. Give it a ğŸ‘� if you want it in Go!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn:why&quot;&gt;
&lt;p&gt;IPv4-mapped IPv6 addresses let you handle only IPv6 addresses in your code
and keep conversions at a few well-defined boundaries. I use them in
&lt;a href=&quot;https://github.com/akvorado/akvorado&quot; title=&quot;Akvorado: flow collector, enricher and visualizer&quot;&gt;Akvorado&lt;/a&gt;.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:why&quot; title=&quot;Jump back to footnote 1 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:equiv&quot;&gt;
&lt;p&gt;This is not strictly equivalent. The zero value becomes &lt;code&gt;::&lt;/code&gt; while it would
make more sense to leave it untouched.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:equiv&quot; title=&quot;Jump back to footnote 2 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:inconvenient&quot;&gt;
&lt;p&gt;I suppose Go maintainers keep it inconvenient on purpose: they donâ€™t want
random packages to patch the standard library or other packages.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:inconvenient&quot; title=&quot;Jump back to footnote 3 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:tests&quot;&gt;
&lt;p&gt;To avoid catastrophic bugs when &lt;code&gt;netip.Addr&lt;/code&gt;â€™s layout changes, you must &lt;a href=&quot;https://github.com/vincentbernat/go-netip-addrto6/blob/main/ipv6_unsafe_test.go&quot; title=&quot;Tests for unsafe AddrTo6() function&quot;&gt;add
tests&lt;/a&gt; to detect it. This is more dangerous if you put this code in a
package. Either ask users to run the tests themselves, or detect the change
at run time and panic. Hiding this optimization behind a build tag would
make users aware of this potential trap.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:tests&quot; title=&quot;Jump back to footnote 4 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:dis&quot;&gt;
&lt;p&gt;I produced the assembly code with &lt;code&gt;GOTOOLCHAIN=go1.26.8 GOAMD64=v3 ./go-asm
&#39;\.asm&#39;&lt;/code&gt; from the &lt;a href=&quot;https://github.com/vincentbernat/go-netip-addrto6&quot;&gt;companion repository&lt;/a&gt;, then edited it a bit to keep this
article from turning into an endless rabbit hole. Due to an unfortunate
sequence of events, we switch between versions: Goâ€¯1.27 introduced a
regression that blurs the point of this article.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:dis&quot; title=&quot;Jump back to footnote 5 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:inline&quot;&gt;
&lt;p&gt;The function is short enough for the compiler to inline it, so the assembly
code may vary depending on the surrounding code.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:inline&quot; title=&quot;Jump back to footnote 6 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:amd64v3&quot;&gt;
&lt;p&gt;&lt;code&gt;MOVBEQ&lt;/code&gt; requires &lt;code&gt;GOAMD64=v3&lt;/code&gt;, matching the &lt;a href=&quot;https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels&quot; title=&quot;X86-64 on Wikipedia&quot;&gt;x86-64-v3
microarchitecture&lt;/a&gt; from 2013. Otherwise, the compiler translates
&lt;code&gt;BEPutUint64()&lt;/code&gt; to &lt;code&gt;BSWAPQ&lt;/code&gt;+&lt;code&gt;MOVQ&lt;/code&gt; and &lt;code&gt;BEUint64()&lt;/code&gt; to &lt;code&gt;MOVQ&lt;/code&gt;+&lt;code&gt;BSWAPQ&lt;/code&gt;.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:amd64v3&quot; title=&quot;Jump back to footnote 7 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:statement&quot;&gt;
&lt;p&gt;When the call is used as a statement, a struct literal alone is invalid. The
patch then turns it into &lt;code&gt;_ = netip.Addr{â€¦}&lt;/code&gt;.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:statement&quot; title=&quot;Jump back to footnote 8 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:html&quot;&gt;
&lt;p&gt;The compiler can also write an HTML file with the result of each pass:&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOSSAFUNC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AddrTo6Safe&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOTOOLCHAIN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;go1.26.8&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOAMD64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;v3&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;go&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;build&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-a&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.
&lt;span class=&quot;go&quot;&gt;dumped SSA for AddrTo6Safe,1 to ./ssa.html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:html&quot; title=&quot;Jump back to footnote 9 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:lines&quot;&gt;
&lt;p&gt;Source line numbers in parentheses follow value identifiers, but I removed
them from the examples. The &lt;abbr title=&quot;Static Single Assignment&quot;&gt;SSA&lt;/abbr&gt; form also features branches, but we donâ€™t
need them to understand our optimizations.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:lines&quot; title=&quot;Jump back to footnote 10 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Sun, 04 Oct 2026 14:12:19 +0000</pubDate>

</item> 
<item>
	<title>Steinar H. Gunderson: Decompilation patterns part 1: Anti-CSE</title>
	<guid>http://blog.sesse.net/blog/tech/2026-10-04-10-16_decompilation_patterns_part_1_anti_cse.html</guid>
	<link>http://blog.sesse.net/blog/tech/2026-10-04-10-16_decompilation_patterns_part_1_anti_cse.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/sesse.png&quot; width=&quot;74&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;There&#39;s a lot of¹ interest in decompilation these days; taking some old
piece of software (usually a game) and try to reconstruct C that does
the same thing. (This is often for modding purposes, but also often
for understanding, or just as a personal challenge.) An often sought-after
property is &lt;em&gt;matching&lt;/em&gt;; that the decompiled C produces 100% the same bytes
as the original after compilation. (This means you&#39;ll need to find the
original compiler and build flags, of course.) Typically, one starts
with the disassembled code and runs &lt;a href=&quot;https://github.com/matt-kempster/m2c&quot;&gt;m2c&lt;/a&gt;
on it, which then spits out some C that is fairly close to the original,
but rarely produces a match without further cleanup. (It is usually
much closer to a match than what Ghidra or Hex-Rays would output; Ghidra is made
for ease of understanding, not matching, so it tends to simplify a lot.)&lt;/p&gt;

&lt;p&gt;Cleaning up the code for matching has two main advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It usually makes the source easier to understand, and&lt;/li&gt;
&lt;li&gt;Matching is a very strong argument (though not infallible)
that the decompilation is actually correct.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Like with pretty much any other field these days, there is a lot of interest
in giving this task to some LLM, which means there&#39;s now a lot of
decompilations around that match (fitting #2 perfectly) and completely
fail #1. :-) Anyway, at some point, I learned that there is almost no
public documentation on the cleaning-up-for-matching part; it&#39;s all folklore
and people rediscovering the same patterns. So I thought I&#39;d do something
about that².&lt;/p&gt;

&lt;p&gt;My general goal is to write up one decompilation pattern a day (focusing
on what I know best, namely GCC on MIPS), with some
example. Most of them will be very simple; some are much less obvious.
I&#39;ll keep going until I run out of ideas. None are formally named, so
I&#39;ll just invent a name. So here goes part one:&lt;/p&gt;

&lt;pre&gt;  temp_v0_5 = g_state.players[1].unk2;
  if ((temp_v0_5 != 7) &amp;amp;&amp;amp; (temp_v0_5 != 0)) {
&lt;/pre&gt;

&lt;p&gt;What happened here is usually that the compiler has done &lt;em&gt;common subexpression elimination&lt;/em&gt;;
someone wrote the same thing twice and then the compiler decided to just
calculate it once and put it into a temporary variable. (Or the programmer
did, in which case you would be wise to leave it alone! Getting into the
original programmer&#39;s head is part of the challenge.) This will often
affect register allocation and/or stack layout, so to get a better match,
you could try doing CSE in reverse:&lt;/p&gt;

&lt;pre&gt;  if (g_state.players[1].unk2 != 7 &amp;amp;&amp;amp; g_state.players[1].unk2 != 0) {
&lt;/pre&gt;

&lt;p&gt;Nothing is mechanical; it may help or it may not. (It may also appear to
hurt at first and then help later, or vice versa.) But anti-CSE is generally
very common and you&#39;ll want to have it in your arsenal.&lt;/p&gt;

&lt;p&gt;¹ Well, all is relative.&lt;/p&gt;

&lt;p&gt;² Reluctantly, with the understanding that the LLMs might also learn from it.&lt;/p&gt; </description> 
	<pubDate>Sun, 04 Oct 2026 09:16:00 +0000</pubDate>

</item> 
<item>
	<title>Vincent Bernat: Self-hosted HTTP tunnels with SSH and nginx</title>
	<guid>http://www.luffy.cx/en/blog/2026-http-over-ssh.html</guid>
	<link>https://vincent.bernat.ch/en/blog/2026-http-over-ssh</link>
     <description>  &lt;p&gt;A friend wants to proofread your work-in-progress blog post, but its preview
only runs on &lt;code&gt;localhost:8080&lt;/code&gt;. &lt;a href=&quot;https://github.com/anderspitman/awesome-tunneling&quot; title=&quot;awesome-tunneling: a list of tunneling software and services&quot;&gt;Several tools&lt;/a&gt; can help. Some run as a
commercial service, like &lt;a href=&quot;https://ngrok.com/&quot; title=&quot;ngrok&quot;&gt;ngrok&lt;/a&gt; or &lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/&quot; title=&quot;Quick Tunnels with TryCloudflare&quot;&gt;Cloudflare Quick Tunnels&lt;/a&gt;. Some are
self-hostable but require a specific client, like &lt;a href=&quot;https://github.com/fatedier/frp&quot; title=&quot;frp: a fast reverse proxy&quot;&gt;frp&lt;/a&gt; or &lt;a href=&quot;https://github.com/localtunnel/localtunnel&quot; title=&quot;localtunnel: expose your localhost to the world&quot;&gt;localtunnel&lt;/a&gt;.
Some only require a plain SSH client but rely on a specific SSH server, like
&lt;a href=&quot;https://docs.ssi.sh/&quot; title=&quot;sish: host public web services on localhost&quot;&gt;sish&lt;/a&gt;. Let’s implement a self-hosted solution with only &lt;em&gt;OpenSSH&lt;/em&gt; and
&lt;em&gt;nginx&lt;/em&gt;!&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;ssh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-R&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;:localhost:8080&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;http-over-ssh
&lt;span class=&quot;go&quot;&gt;Allocated port 41535 for remote forward to localhost:8080&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;https://6J3jK1WmB15c6WmjW_X-Wg--1789928654@p41535.ssh.luffy.cx/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1 id=&quot;basic-setup&quot;&gt;Basic setup&lt;/h1&gt;
&lt;p&gt;First, we forward connections from a port on a remote server to your local
service:&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;ssh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-N&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-R&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;:localhost:8080&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;web02.luffy.cx
&lt;span class=&quot;go&quot;&gt;Allocated port 41535 for remote forward to localhost:8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you specify &lt;code&gt;0&lt;/code&gt; as the remote port, the server allocates a free port.
Then, we configure nginx to proxy requests from &lt;code&gt;https://p41535.ssh.luffy.cx&lt;/code&gt; to
&lt;code&gt;http://127.0.0.1:41535&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-nginx-configuration-file codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[::0]:443&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;server_name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;^p(?&amp;lt;port&amp;gt;\d\d\d\d\d)\.ssh\.luffy\.cx$;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_pass&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://127.0.0.1:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We also need to add DNS records for &lt;code&gt;*.ssh.luffy.cx&lt;/code&gt; and get a wildcard
certificate through &lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;language-zone codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;*.ssh.luffy.cx.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;               &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CNAME&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;l&quot;&gt;web02.luffy.cx.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ssh.luffy.cx.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                 &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CAA&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;l&quot;&gt;issuewild&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;letsencrypt.org&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;_acme-challenge.ssh.luffy.cx&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CNAME&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;l&quot;&gt;ssh.luffy.cx.acme.luffy.cx.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;acme.luffy.cx&lt;/code&gt; is a zone hosted on Route 53. I use it for &lt;a href=&quot;https://letsencrypt.org/docs/challenge-types/#dns-01-challenge&quot; title=&quot;DNS-01 challenge&quot;&gt;ACME DNS-01
challenges&lt;/a&gt;, both for wildcard certificates and for domains served by
several web servers. In my case, NixOS &lt;a href=&quot;https://wiki.nixos.org/wiki/ACME&quot; title=&quot;ACME on the NixOS Wiki&quot;&gt;gets the certificates
automatically&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;access-control&quot;&gt;Access control&lt;/h1&gt;
&lt;p&gt;The port is the only “secret”&lt;sup id=&quot;fnref:port&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:port&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; keeping the content confidential. Other
forwarding solutions add a random string to the domain name to prevent an
intruder from enumerating the possible values.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://nginx.org/en/docs/http/ngx_http_secure_link_module.html&quot; title=&quot;Module ngx_http_secure_link_module for nginx&quot;&gt;&lt;code&gt;ngx_http_secure_link_module&lt;/code&gt;&lt;/a&gt;, we can secure
this setup a bit. This module computes a hash&lt;sup id=&quot;fnref:md5&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:md5&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; over a set of values,
including a secret, and compares it with the hash from the request. The hash is
base64-encoded, so we cannot put it in the domain name, which is
case-insensitive. Instead, we put it in the URL as a username, along with its
expiration timestamp:&lt;sup id=&quot;fnref:expiration&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:expiration&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-text-only codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://6J3jK1WmB15c6WmjW_X-Wg--1789928654@p41535.ssh.luffy.cx/en/blog
        ╰─────────┬──────────╯  ╰───┬────╯  ╰─┬─╯             ╰──┬───╯
                hash             expires    port               path
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The client sends the username to the server with &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc7617&quot; title=&quot;RFC 7617: The &#39;Basic&#39; HTTP Authentication Scheme&quot;&gt;HTTP basic
authentication&lt;/a&gt;. This works with most HTTP clients, including &lt;code&gt;curl&lt;/code&gt;.
Nginx exposes the username in the &lt;code&gt;$remote_user&lt;/code&gt; variable. The module expects
the hash and the expiration timestamp separated by a comma. We use a &lt;code&gt;map&lt;/code&gt;
directive to extract the two parts from &lt;code&gt;$remote_user&lt;/code&gt; and join them with a
comma.&lt;sup id=&quot;fnref:comma&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:comma&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; We also give the module the string to hash. It contains the
expiration timestamp, the port, and a secret:&lt;/p&gt;
&lt;div class=&quot;language-nginx-configuration-file codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remote_user&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$httpssh_link&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;&quot;~^([-_A-Za-z0-9]{22})--([0-9]+)$&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1,$2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# […]&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;secure_link&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$httpssh_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;secure_link_md5&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secure_link_expires&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ZuPerS3cr3!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The module returns the status of the check in the &lt;code&gt;$secure_link&lt;/code&gt; variable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;empty if the hashes do not match,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;0&quot;&lt;/code&gt; if they match but the link has expired, or&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;1&quot;&lt;/code&gt; otherwise.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the hash is incorrect or missing, we return a 401 error with a
&lt;code&gt;WWW-Authenticate&lt;/code&gt; header to ask for credentials. If the link has expired, we
return a 410 error. We remove the &lt;code&gt;Authorization&lt;/code&gt; header before forwarding the
request and add a few directives to &lt;a href=&quot;https://nginx.org/en/docs/http/websocket.html&quot; title=&quot;nginx documentation: WebSocket proxying&quot;&gt;proxy WebSocket connections&lt;/a&gt;.
Here is the complete configuration:&lt;sup id=&quot;fnref:security&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:security&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-nginx-configuration-file codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remote_user&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$httpssh_link&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;&quot;~^([-_A-Za-z0-9]{22})--([0-9]+)$&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1,$2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[::0]:443&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;server_name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;^p(?&amp;lt;port&amp;gt;\d\d\d\d\d)\.ssh\.luffy\.cx$;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;secure_link&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$httpssh_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;secure_link_md5&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secure_link_expires&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ZuPerS3cr3!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secure_link&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;add_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;WWW-Authenticate&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#39;Basic&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;realm=&quot;tunnel&quot;&#39;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;always&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;401&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secure_link&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;410&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_pass&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://127.0.0.1:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;X-Forwarded-For&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Authorization&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_http_version&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Upgrade&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Connection&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;upgrade&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_buffering&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_read_timeout&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I think you are now asking yourself the obvious question: “How should I generate
the hash?” Easy peasy!&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;+%s&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;41535&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;ZuPerS3cr3!&#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;%s %s %s&#39;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$expires&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secret&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openssl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;md5&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-binary&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openssl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;base64&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;+/&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-_&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-d&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6J3jK1WmB15c6WmjW_X-Wg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Well, I suppose you are now saying: “Vincent, this is not very convenient! I’ll stick
with ngrok if you don’t mind.” Okay, I hear you. Let’s write a helper script.&lt;/p&gt;
&lt;h1 id=&quot;helper-script&quot;&gt;Helper script&lt;/h1&gt;
&lt;p&gt;The main difficulty is finding the ephemeral port that OpenSSH allocates, as it
does not appear in any environment variable.&lt;sup id=&quot;fnref:env&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:env&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; To work around this obstacle,
we look for the ancestor &lt;code&gt;sshd-session&lt;/code&gt; processes:&lt;sup id=&quot;fnref:sshd-session&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:sshd-session&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;pids&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$$&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pid&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-gt&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;ps&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-o&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;comm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;,pid&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;,ppid&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-p&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pid&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$line&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;##* &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;awk&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;$1 == &quot;sshd-session&quot; { printf &quot;pid=%s,\n&quot;, $2 }&#39;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-z&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pids&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;not an ssh session&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, we get the listening ports associated with these &lt;code&gt;sshd-session&lt;/code&gt;
processes:&lt;sup id=&quot;fnref:sudo&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:sudo&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;sudo&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-n&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;ss&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--listening&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--numeric&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--tcp&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--processes&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--no-header&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;grep&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-F&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pids&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;awk&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;{ print $4 }&#39;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;awk&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-F:&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;{ print $NF }&#39;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;sort&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-un&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-z&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ports&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;no forwarded port, use ssh -R 0:localhost:PORT&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, we display the URLs and keep the session open:&lt;/p&gt;
&lt;div class=&quot;language-bash codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;lifetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;86400&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;ZuPerS3cr3!&#39;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;+%s&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lifetime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;port&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;%s %s %s&#39;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$expires&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secret&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openssl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;md5&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-binary&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openssl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;base64&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;+/&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-_&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tr&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-d&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$expires&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;@p&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$port&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.ssh.luffy.cx/&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
sleep&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;infinity
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I install this script as &lt;code&gt;http-over-ssh&lt;/code&gt; on the server and add this entry to my
&lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-ssh-config codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;http-over-ssh
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Hostname&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;web02.luffy.cx
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;RemoteCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;http-over-ssh
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ControlPath&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;none
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With this solution, I only rely on OpenSSH and nginx, two pieces of software
already running on this server. One short command gives me a self-hosted tunnel
and a URL to share. To try it, grab the &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/tags/http-over-ssh.sh&quot; title=&quot;nixops-take1/tags/http-over-ssh.sh at master&quot;&gt;complete helper script&lt;/a&gt;, which
includes a few minor improvements. If you run NixOS, as any person of taste
would, have a look at my &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/tags/http-over-ssh.nix&quot; title=&quot;nixops-take1/tags/http-over-ssh.nix at master&quot;&gt;&lt;code&gt;http-over-ssh.nix&lt;/code&gt;&lt;/a&gt; instead. ❄️&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn:port&quot;&gt;
&lt;p&gt;Since the kernel allocates it from the local port range, its entropy is low.
Moreover, on Linux, we lose one more bit because the kernel &lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/inet_connection_sock.c?h=v7.2#n349&quot; title=&quot;net/ipv4/inet_connection_sock.c&quot;&gt;favors odd
ports&lt;/a&gt; when it picks a random free port.&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;sysctl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-n&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;net.ipv4.ip_local_port_range&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;awk&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;{print $1&quot;—&quot;$2&quot; ≈ &quot;log($2-$1+1)/log(2)&quot; bits&quot;}&#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;32768—60999 ≈ 14.785 bits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:port&quot; title=&quot;Jump back to footnote 1 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:md5&quot;&gt;
&lt;p&gt;The module relies on MD5. Its security is weak but good enough for this
use. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:md5&quot; title=&quot;Jump back to footnote 2 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:expiration&quot;&gt;
&lt;p&gt;We need an expiration date because a later session could reuse the port,
and we have no way to detect this case. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:expiration&quot; title=&quot;Jump back to footnote 3 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:comma&quot;&gt;
&lt;p&gt;The username could use a comma directly instead of a double dash. But some
applications do not recognize the URL correctly, making it harder to share. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:comma&quot; title=&quot;Jump back to footnote 4 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:security&quot;&gt;
&lt;p&gt;This configuration exposes any TCP port listening on &lt;code&gt;127.0.0.1&lt;/code&gt; or
&lt;code&gt;0.0.0.0&lt;/code&gt; to anyone with the secret, bypassing most firewall rules. You
could strengthen it by limiting the &lt;code&gt;server_name&lt;/code&gt; regex to the ephemeral
port range. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:security&quot; title=&quot;Jump back to footnote 5 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:env&quot;&gt;
&lt;p&gt;One SSH session can contain several tunnels, and the client can add or
remove them at any time. This is unlike tun device forwarding (&lt;code&gt;ssh -w&lt;/code&gt;),
which gets its own &lt;code&gt;SSH_TUNNEL&lt;/code&gt; environment variable. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:env&quot; title=&quot;Jump back to footnote 6 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:sshd-session&quot;&gt;
&lt;p&gt;Since OpenSSH 9.8, &lt;code&gt;sshd-session&lt;/code&gt; is the name of the helper handling the
session. With older versions, look for &lt;code&gt;sshd&lt;/code&gt; instead. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:sshd-session&quot; title=&quot;Jump back to footnote 7 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:sudo&quot;&gt;
&lt;p&gt;We need &lt;code&gt;sudo&lt;/code&gt; because the &lt;code&gt;sshd-session&lt;/code&gt; process dropped its privileges.
The kernel then marks it as not dumpable, and its &lt;a href=&quot;https://manpages.debian.org/proc_pid.5.html&quot; title=&quot;Manual page for proc_pid(5)&quot;&gt;&lt;code&gt;/proc/PID/fd&lt;/code&gt; directory
belongs to root&lt;/a&gt;. Without access to this directory, &lt;code&gt;ss&lt;/code&gt; cannot
find which process owns a socket. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:sudo&quot; title=&quot;Jump back to footnote 8 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Sat, 03 Oct 2026 07:23:12 +0000</pubDate>

</item> 
<item>
	<title>Ben Hutchings: FOSS activity in September 2026</title>
	<guid>https://www.decadent.org.uk/ben/blog/2026/10/02/foss-activity-in-september-2026</guid>
	<link>https://www.decadent.org.uk/ben/blog/2026/10/02/foss-activity-in-september-2026.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/benh.png&quot; width=&quot;109&quot; height=&quot;100&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;ul&gt;
  &lt;li&gt;Debian packages:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/firmware-nonfree&quot;&gt;firmware-nonfree&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/src:firmware-nonfree&quot;&gt;Bugs&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://bugs.debian.org/1148284&quot;&gt;#1148284: firmware-amd-graphics: AMD AV1 hardware decoding produces severe video artifacts with firmware 20260810-1&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;opened and merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/firmware-nonfree/-/merge_requests/154&quot;&gt;!154: Update to 20260916; fix some license information&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/firmware-nonfree/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 20260810-1~bpo13+1 to trixie-backports&lt;/li&gt;
              &lt;li&gt;uploaded version 20260916-1 to unstable&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/initramfs-tools&quot;&gt;initramfs-tools&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://salsa.debian.org/kernel-team/initramfs-tools/-/merge_requests/202&quot;&gt;!202: mkinitramfs: fix path to kernel config in /lib/modules&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/kernel-team&quot;&gt;kernel-team&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/kernel-team/-/merge_requests/14&quot;&gt;!14: find-recent-urgent: Sort bugs from linux first&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;opened &lt;a href=&quot;https://salsa.debian.org/kernel-team/kernel-team/-/merge_requests/15&quot;&gt;!15: Add form responses for common problems with bug reports&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux&quot;&gt;linux&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/src:linux&quot;&gt;Bugs&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://bugs.debian.org/1146373&quot;&gt;#1146373: linux-libc-dev: sbrk(2) allocates more than memory + swap space&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2010&quot;&gt;!2010: [x86] Backport security fixes for KVM&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2083&quot;&gt;!2083: linux-image: Bump Pre-Depends version on linux-base (&amp;gt;= 4.17~)&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;reviewed and merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2095&quot;&gt;!2095: 6.1 stable updates&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2108&quot;&gt;!2108: [alpha] Reenable CONFIG_COMPACTION&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2109&quot;&gt;!2109: Enable BMI323 support as a module&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2110&quot;&gt;!2110: riscv64 config update for linux 7.3&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 7.1.13-1~bpo13+1 to trixie-backports&lt;/li&gt;
              &lt;li&gt;uploaded version 7.2.6-1~bpo13+1 to trixie-backports&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-6.1&quot;&gt;linux-6.1&lt;/a&gt; (LTS):
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/src:linux-6.1&quot;&gt;Bugs&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://bugs.debian.org/1117674&quot;&gt;#1117674: Please enable udebs for the 6.1 backport&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-6.12&quot;&gt;linux-6.12&lt;/a&gt; (LTS):
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-6.12/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 6.12.107-1~deb12u1 to bookworm-security&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;merged changes from trixieâ€™s 6.12.111-1&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-base&quot;&gt;linux-base&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-base/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 4.17~bpo13+1 to trixie-backports&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/nfs-utils&quot;&gt;nfs-utils&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;reviewed &lt;a href=&quot;https://salsa.debian.org/kernel-team/nfs-utils/-/merge_requests/37&quot;&gt;!37: Install and use sysusers.d/tmpfiles.d config files&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/wireless-regdb&quot;&gt;wireless-regdb&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/wireless-regdb/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 2026.09.03-1 to unstable&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Mailing lists:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://lists.debian.org/debian-kernel/&quot;&gt;debian-kernel&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/9c807a025be2c54c60792124b0ef4210feda5aeb.camel@decadent.org.uk&quot;&gt;Agenda items for kernel-team meeting on 2026-09-30&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;replied to &lt;a href=&quot;https://lists.debian.org/9becdbad09e5c8180d83cab692313ae1b445e9b6.camel@decadent.org.uk&quot;&gt;Meta packages for modules&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;replied to &lt;a href=&quot;https://lists.debian.org/9cf5c87217aac57405690daa34660786a33b0f8c.camel@decadent.org.uk&quot;&gt;Updating linux-6.12 (bookworm-security) to 6.12.107&lt;/a&gt; (LTS)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://lists.debian.org/debian-lts-announce/&quot;&gt;debian-lts-announce&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/aq70MTniNMFjPuqA@decadent.org.uk&quot;&gt;[SECURITY] [DLA 4788-1] linux-6.12 security update&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt; </description> 
	<pubDate>Fri, 02 Oct 2026 14:34:15 +0000</pubDate>

</item> 
<item>
	<title>Junichi Uekawa: Tokyo has been raining for many days but finally there&#39;s some sunny days.</title>
	<guid>http://www.netfort.gr.jp/~dancer/diary/daily/2026-Oct-2.html.en#2026-Oct-2-16:56:37</guid>
	<link>http://www.netfort.gr.jp/~dancer/diary/daily/2026-Oct-2.html.en#2026-Oct-2-16:56:37</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dancer.png&quot; width=&quot;75&quot; height=&quot;97&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  Tokyo has been raining for many days but finally there&#39;s some sunny days.
        &lt;p&gt;&lt;/p&gt; </description> 
	<pubDate>Fri, 02 Oct 2026 07:56:37 +0000</pubDate>

</item> 
<item>
	<title>Dirk Eddelbuettel: RcppFastAD 0.0.6 on CRAN: Agentic Fix</title>
	<guid>http://dirk.eddelbuettel.com/blog/2026/10/01#rcppfastad_0.0.6</guid>
	<link>http://dirk.eddelbuettel.com/blog/2026/10/01#rcppfastad_0.0.6</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dirk.png&quot; width=&quot;65&quot; height=&quot;90&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;A week ago, &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/2026/09/24#rcppfastad_0.0.5&quot;&gt;release
0.0.5&lt;/a&gt; of the &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;RcppFastAD&lt;/a&gt; package
went to &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt;, and &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/2026/09/24#rcppfastad_0.0.5&quot;&gt;we
noted&lt;/a&gt; that it provided a stop-gap measure against a gnarly segfault
with &lt;code&gt;g++-16&lt;/code&gt; under heavier optimization / inlining. We are
happy to now announce that a new and fixed version 0.0.6 of &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;RcppFastAD&lt;/a&gt; is now
on &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt;, and has been built for
&lt;a href=&quot;https://eddelbuettel.github.io/r2u/&quot;&gt;r2u&lt;/a&gt; as well as at &lt;a href=&quot;https://eddelbuettel.r-universe.dev/RcppFastAD&quot;&gt;r-universe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;RcppFastAD&lt;/a&gt;
wraps the &lt;a href=&quot;https://github.com/JamesYang007/FastAD&quot;&gt;FastAD&lt;/a&gt;
header-only C++ library by &lt;a href=&quot;https://github.com/JamesYang007&quot;&gt;James&lt;/a&gt; which provides a C++
implementation of both forward and reverse mode of automatic
differentiation. It offers an easy-to-use header library that is both
lightweight and performant. With a little of bit of &lt;a href=&quot;https://www.rcpp.org&quot;&gt;Rcpp&lt;/a&gt; glue, it is also easy to use from R
in simple C++ applications.&lt;/p&gt;
&lt;p&gt;This release takes advantage of some large-language model inference
access I now get via Debian. The Deepseek v4 flash-0731 model, driven in
a container via the pi.dev harness, took just about no time finding a
small workaround for the issue &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/2026/09/24#rcppfastad_0.0.5&quot;&gt;described
last week&lt;/a&gt; where we could see segfaults under heavier optimization
and inlining. The fix was to prohibit inlining the local
&lt;code&gt;bind()&lt;/code&gt; reimplementation. We have also sent this upstream as
a patch. It is nice to have an option of querying something a little
more powerful than the local models I experimented with before. We
suppress more compiler warnings in local builds via another option, and
did some standard maintenance.&lt;/p&gt;
&lt;p&gt;The NEWS file for this release follows.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;changes-in-version-0.0.6-2026-10-01&quot;&gt;Changes in version 0.0.6
(2026-10-01)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The expression-template view rebinding is protected against
&lt;code&gt;g++ -O3&lt;/code&gt; (which led to wrong &lt;code&gt;Eigen::Map&lt;/code&gt;
dimensions, an &lt;code&gt;Eigen::Map&lt;/code&gt; resize assertion, and a
segfault.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;bind()&lt;/code&gt; helpers are marked non-inline and are
also protected from operating on a &lt;code&gt;nullptr&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Both items co-written with DeepSeek V4 Flash, and have been sent
upstream in a PR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppress another compiler warning when local build
detected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add r-universe badge to README.md.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Courtesy of my &lt;a href=&quot;https://dirk.eddelbuettel.com/cranberries/&quot;&gt;CRANberries&lt;/a&gt;, there
is also a diffstat report for the &lt;a href=&quot;https://dirk.eddelbuettel.com/cranberries/2026/10/01#RcppFastAD_0.0.6&quot;&gt;most
recent release&lt;/a&gt;. More information is available at the &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;repository&lt;/a&gt; or the
&lt;a href=&quot;https://dirk.eddelbuettel.com/code/rcpp.fastad.html&quot;&gt;package
page&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;font-size: 80%; font-style: italic;&quot;&gt;
This post by &lt;a href=&quot;https://dirk.eddelbuettel.com&quot;&gt;Dirk
Eddelbuettel&lt;/a&gt; originated on his &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/&quot;&gt;Thinking inside the box&lt;/a&gt;
blog. If you like this or other open-source work I do, you can now &lt;a href=&quot;https://github.com/sponsors/eddelbuettel&quot;&gt;sponsor me at
GitHub&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt; </description> 
	<pubDate>Thu, 01 Oct 2026 17:05:00 +0000</pubDate>

</item> 
<item>
	<title>Daniel Pocock: Reform UK, Nigel Farageâ€™s party/company, admits missing [redacted]</title>
	<guid>https://danielpocock.com/en/nigel-farage-reform-uk-admits-missing-legal-documents</guid>
	<link>https://danielpocock.com/en/nigel-farage-reform-uk-admits-missing-legal-documents/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/pocock.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;In my other blog today, I explored how the other
&lt;a href=&quot;https://danielpocock.com/en/creditors-beware-vms-enterprises-brexit-party-reform-uk/&quot;&gt;
Reform UK Party Limited party/company was previously subject to
a judgment and insolvency proceedings to try and extract payment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Very few companies are ever listed in the official Gazette.&lt;/p&gt;

&lt;p&gt;After that painful lesson, as they progress towards being in a position
to run the UK Government, wouldn&#39;t you expect them to improve their
procedures and run their party headquarters competently?&lt;/p&gt;

&lt;p&gt;When
&lt;a href=&quot;https://danielpocock.com/en/people/sarah-cooper-lesadd/&quot;&gt;
Sarah Cooper-Lesadd&lt;/a&gt; recently resigned and defected from
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt;, she
&lt;a href=&quot;https://www.bbc.com/audio/play/p0p9xklk&quot;&gt;told&lt;/a&gt; the
&lt;a href=&quot;https://danielpocock.com/en/category/bbc/&quot;&gt;
BBC&lt;/a&gt; that
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; is chaotic.&lt;/p&gt;

&lt;p&gt;In the
&lt;a href=&quot;https://danielpocock.com/en/creditors-beware-vms-enterprises-brexit-party-reform-uk/&quot;&gt;
Scotsman&#39;s report about the VMS Enterprises vs Brexit Party dispute&lt;/a&gt;, the party
was described as &quot;beyond chaotic&quot;.  They can&#39;t seem to learn how to
tie their shoelaces but they want to run the
&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
United Kingdom&lt;/a&gt;.  If
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; does ever become Prime Minister, I hope his party remembers
to pass on the messages when
&lt;a href=&quot;https://danielpocock.com/en/category/argentina/&quot;&gt;
Argentina&lt;/a&gt; makes their next attempt to take the Falkland Islands.&lt;/p&gt;

&lt;img alt=&quot;Sarah Cooper-Lesadd&quot; src=&quot;https://danielpocock.com/assets/people/sarah-cooper-lesadd/sarah-cooper-lesadd.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;It looks like
&lt;a href=&quot;https://danielpocock.com/en/people/sarah-cooper-lesadd/&quot;&gt;
Sarah Cooper-Lesadd&lt;/a&gt;
is right.  They admit despite having one of the most serious legal
documents, a [redacted], served on their party headquarters,
they have no idea where it went:&lt;/p&gt;

&lt;img alt=&quot;Tom Waterhouse, General Secretary, Reform UK&quot; src=&quot;https://danielpocock.com/assets/reform-uk/missing-petition.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Fortunately, the process server provide video evidence so I can prove it
was served correctly and the incompetence is not on my side.&lt;/p&gt;

&lt;p&gt;In fact, the case only reached this point because of a litany of errors on
the part of
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; themselves.  Errors they should never have made if they learnt
the lesson from
&lt;a href=&quot;https://danielpocock.com/en/creditors-beware-vms-enterprises-brexit-party-reform-uk/&quot;&gt;
the somebody who brought their party into insolvency proceedings in 2022&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Look at the cost.  Their lawyers,
&lt;a href=&quot;https://danielpocock.com/en/category/aston-bond/&quot;&gt;
Aston Bond&lt;/a&gt;, have invoiced over £25,000 before the first hearing.
Most of that is for investigating what went wrong inside their own
organisation and how the dispute was
&lt;a href=&quot;https://danielpocock.com/en/winding-up-petition-leaked-before-service-reform-uk-party-limited/&quot;&gt;
leaked by the MouseInTheCourt&lt;/a&gt; before the [redacted] ever arrived on
the doorstep of party HQ.&lt;/p&gt;

&lt;img alt=&quot;Aston Bond, invoice, Nigel Farage, Reform UK&quot; src=&quot;https://danielpocock.com/assets/aston-bond/20260929-costs-page-1.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;img alt=&quot;Aston Bond, invoice, Nigel Farage, Reform UK&quot; src=&quot;https://danielpocock.com/assets/aston-bond/20260929-costs-page-2.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;img alt=&quot;Aston Bond, invoice, Nigel Farage, Reform UK&quot; src=&quot;https://danielpocock.com/assets/aston-bond/20260929-costs-page-3.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;img alt=&quot;Aston Bond, invoice, Nigel Farage, Reform UK&quot; src=&quot;https://danielpocock.com/assets/aston-bond/20260929-costs-page-4.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;img alt=&quot;Aston Bond, invoice, Nigel Farage, Reform UK&quot; src=&quot;https://danielpocock.com/assets/aston-bond/20260929-costs-page-5.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Why is
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; so so afraid of a candidate who only got sixteen votes?&lt;/p&gt;

&lt;p&gt;Read more about the
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
various judgments in the history of Reform UK Party Limited&lt;/a&gt;.&lt;/p&gt; </description> 
	<pubDate>Thu, 01 Oct 2026 10:00:00 +0000</pubDate>

</item> 
<item>
	<title>Daniel Pocock: Creditors beware: VMS Enterprises Ltd vs Brexit Party (Reform UK Party Ltd)</title>
	<guid>https://danielpocock.com/en/creditors-beware-vms-enterprises-brexit-party-reform-uk</guid>
	<link>https://danielpocock.com/en/creditors-beware-vms-enterprises-brexit-party-reform-uk/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/pocock.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;As
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; tries to [redacted], they have complained
to the court that [redacted] other failed candidates,
Reform UK defectors, independent contractors and small business owners
&lt;a href=&quot;https://danielpocock.com/en/supporters-winding-up-process-invited-reform-uk-party/&quot;&gt;
how to [redacted]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If they block more people [redacted]&lt;/p&gt;

&lt;p&gt;It is not my intention to publish the forms unless the conduct and
behaviour of these people forces me to do so.&lt;/p&gt;

&lt;h3&gt;Judgment: VMS Enterprises Ltd vs The Brexit Party Ltd ([2021] SC GLA 49)&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;The Brexit Party Ltd&lt;/em&gt; became
&lt;em&gt;Reform UK Party Ltd&lt;/em&gt;, company number 11694875.  This
subsequently got merged into &lt;em&gt;Reform 2025 Ltd&lt;/em&gt; to become a
different &lt;em&gt;Reform UK Party Limited&lt;/em&gt; company no. 16260766.  An
inconvenient consequence of this name change and merger is that people
searching for judgments against the new company number 16260766 don&#39;t
see the history of the old company name and company number.&lt;/p&gt;

&lt;p&gt;The full judgment is available here for download as an Acrobat document:&lt;/p&gt;

&lt;a href=&quot;https://danielpocock.com/assets/reform-uk/2021scgla49-vms-enterprises-ltd-against-the-brexit-party-ltd.pdf&quot;&gt;
&lt;img alt=&quot;VMS Enterprises Ltd vs The Brexit Party Ltd ([2021] SC GLA 49), 11694875, 16260766, CR-2022-003973&quot; src=&quot;https://danielpocock.com/assets/reform-uk/2021scgla49-vms-enterprises-ltd-against-the-brexit-party-ltd-cover.jpg&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://danielpocock.com/en/category/vms-enterprises-ltd/&quot;&gt;
VMS Enterprises Ltd&lt;/a&gt; won the case but it took them over a year to
get paid after the judgment.
&lt;a href=&quot;https://find-and-update.company-information.service.gov.uk/company/SC476412&quot;&gt;
The records about VMS Enterprises Ltd (SC476412) at Companies House show us they
are no longer active&lt;/a&gt;.  It looks like beating
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Brexit Party / Reform UK&lt;/a&gt; in court was only a phyrric victory.&lt;/p&gt;

&lt;p&gt;Not only was there a judgment ([2021] SC GLA 49), there were also some
scholarly research articles published about the dispute:&lt;/p&gt;

&lt;img alt=&quot;Reform UK, Nigel Farage, creditors, [2021] SC GLA 49&quot; src=&quot;https://danielpocock.com/assets/reform-uk/vms-brexit-research-article.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;On 10 September 2021, Scottish Legal News published a detailed summary
&lt;a href=&quot;https://www.scottishlegal.com/articles/glasgow-sheriff-orders-brexit-party-to-pay-22k-in-unpaid-invoices-to-advertising-firm&quot;&gt;
&quot;Glasgow sheriff orders Brexit Party to pay £22k in unpaid invoices to advertising firm&quot;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On 15 November 2021, the case appeared again in
&lt;a href=&quot;https://www.lawscot.org.uk/members/journal/issues/vol-66-issue-11/civil-court-case-management-review/&quot;&gt;
a Law Society of Scotland article about case management review&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Despite the Sheriff making a judgment against the Reform people in July 2021,
they still didn&#39;t pay the bill.  On 19 July 2022, The Scotsman reported
&lt;a href=&quot;https://web.archive.org/web/20220719143728/https://www.scotsman.com/news/politics/reform-uk-face-winding-up-petition-over-ps22000-debt-owed-to-scottish-firm-3774290&quot;&gt;
&quot;Reform UK face winding up petition over £22,000 debt owed to Scottish firm&quot;&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;Quoting the article:&lt;/p&gt;

&lt;blockquote&gt;&lt;em&gt;
The political party, formerly led by Nigel Farage as the Brexit Party during the 2019 general election, faces a hearing in the High Court in London as early as September. Victor Shields, director of VMS Enterprises, was forced to take the party – since rebranded and led by Richard Tice – to court over the bill from the 2019 general election. Despite Glasgow Sheriff Court agreeing the party should pay up, it has consistently refused to answer letters or pay the sum owed to the businessman, forcing him to take further legal action in England. It is understood a winding up petition was served on the political party last week, with a hearing set for September 7 or soon thereafter. Reform UK has consistently rejected the claim, now worth more than £26,000 after interest and before court expenses are taken into account. A winding up order, if granted by the court, would see the party face liquidation proceedings to pay the outstanding amount and could include an investigation into director conduct. The initial Scottish court case arose after a dispute between the party and VMS Enterprises around payment for election billboards in London during the general election campaign. The court stated the party was liable for the bill for advertising services after some invoices were paid by Brexit Party staff and others were not questioned. Several invoices had gone unpaid amid claims a volunteer did not have the authority to charge the party for the billboards. However, the court stated the failure to question the payment of invoices incurred by candidates meant the party was liable for the full costs. Speaking to The Scotsman last year, Mr Shields attacked Reform UK’s “hypocrisy” in failing to pay. He said: “I was quite happy to keep quiet after the judgment because I assumed they would respect the Scottish courts and duly pay us. &quot;They don&#39;t care. They feel they are above the law. &quot;Richard Tice is positioning himself to the right of Boris [Johnson] and trying to capture the Conservative voters, Scottish voters too and here we are being forced to go to English courts, for me being forced to spend further money, to try and recover a debt that is legally due to us.&quot; The court case heard witnesses describe the organisation of the Brexit Party, then led by former UKIP leader Nigel Farage, as &quot;shambolic&quot; by a party official as it struggled to cope with its popularity and decision to pull hundreds of candidates from the ballot paper ahead of polling day. Witnesses told the court the party’s organisational structure &quot;visibly started to fall apart&quot;, was &quot;very unprofessional&quot; and &quot;beyond chaotic&quot; ahead of the 2019 election. Reform UK’s latest accounts state that in 2020 it received nearly £3 million in donations, with a further £17m in 2019. Reform UK has been contacted for comment by The Scotsman.
&lt;/em&gt;&lt;/blockquote&gt;

&lt;p&gt;Eighteen months after the judgment, almost two years after the judicial procedure
began, in December 2022,
&lt;a href=&quot;https://danielpocock.com/en/category/vms-enterprises-ltd/&quot;&gt;
VMS Enterprises Ltd&lt;/a&gt; used the High Court insolvency procedure to publish
an insolvency notice for &lt;em&gt;Reform UK Party Limited&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As a consequence, a listing was placed in the official Gazette with their
old company number 11694875 and the High Court case number CR-2022-003973.&lt;/p&gt;

&lt;h3&gt;Diagram demonstrating evolution of the Reform UK companies&lt;/h3&gt;

&lt;p&gt;Searching for information about the names and company numbers is tedious
and time consuming.  I created a colour-coded diagram so people can see and
understand the relationship between the companies in the history of
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; at a glance.&lt;/p&gt;

&lt;p&gt;Here is what you see if you
&lt;a href=&quot;https://find-and-update.company-information.service.gov.uk/search?q=Reform+UK+Party&quot;&gt;
search for Reform UK at Companies House&lt;/a&gt;.  Which Reform UK is which?&lt;/p&gt;

&lt;img alt=&quot;Reform UK, Nigel Farage, Brexit Party, 11694875, 16260766&quot; src=&quot;https://danielpocock.com/assets/reform-uk/companies-house-search-reform-uk.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Looking through the filing history of each company, you can see many minor
changes, including some name changes.  I put the filing history for both
companies side-by-side:&lt;/p&gt;

&lt;img alt=&quot;Reform UK, Nigel Farage, Brexit Party, 11694875, 16260766&quot; src=&quot;https://danielpocock.com/assets/reform-uk/filing-history-side-by-side.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Drilling down on the name changes, it is fascinating to put the two
forms side-by-side like this:&lt;/p&gt;

&lt;img alt=&quot;Reform UK, Nigel Farage, Brexit Party, 11694875, 16260766&quot; src=&quot;https://danielpocock.com/assets/reform-uk/reform-uk-washes-history.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Here is the full diagram I created to help people understanding the
judgment and insolvency court history of
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; and its leaders at a glance:&lt;/p&gt;

&lt;img alt=&quot;Reform UK, Nigel Farage, Brexit Party, 11694875, 16260766&quot; src=&quot;https://danielpocock.com/assets/reform-uk/name-swap.png&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;img alt=&quot;Reform UK, Nigel Farage, Brexit Party, 11694875, 16260766, CR-2022-003973, [2021] SC GLA 49&quot; src=&quot;https://danielpocock.com/assets/reform-uk/gazette-side-by-side.png&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Direct links to search the Gazette for old company number
&lt;a href=&quot;https://www.thegazette.co.uk/all-notices/notice?sort-by=&amp;amp;results-page-size=10&amp;amp;text=11694875&amp;amp;categorycode%5B%5D=G205010000&amp;amp;noticetypes=&amp;amp;start-publish-date=&amp;amp;end-publish-date=&amp;amp;edition=1&amp;amp;london-issue=&amp;amp;edinburgh-issue=&amp;amp;belfast-issue=&amp;amp;location-postcode-1=&amp;amp;location-distance-1=1&amp;amp;location-local-authority-1=&quot;&gt;11694875&lt;/a&gt;
and for the new company number
&lt;a href=&quot;https://www.thegazette.co.uk/all-notices/notice?sort-by=&amp;amp;results-page-size=10&amp;amp;text=16260766&amp;amp;categorycode%5B%5D=G205010000&amp;amp;noticetypes=&amp;amp;start-publish-date=&amp;amp;end-publish-date=&amp;amp;edition=1&amp;amp;london-issue=&amp;amp;edinburgh-issue=&amp;amp;belfast-issue=&amp;amp;location-postcode-1=&amp;amp;location-distance-1=1&amp;amp;location-local-authority-1=&quot;&gt;16260766&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;People who have a legitimate claim against any company
are encouraged to contact their solicitor for advice
and share their contact details with other creditors to resolve
the dispute more expediently.  See my previous blog about how to
&lt;a href=&quot;https://danielpocock.com/en/supporters-winding-up-process-invited-reform-uk-party/&quot;&gt;
join a creditors petition in the UK&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Read more about the
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
various judgments in the history of Reform UK Party Limited&lt;/a&gt;.&lt;/p&gt; </description> 
	<pubDate>Thu, 01 Oct 2026 07:30:00 +0000</pubDate>

</item> 
<item>
	<title>Daniel Pocock: Reform UK last minute accounts filing</title>
	<guid>https://danielpocock.com/en/reform-uk-last-minute-accounts-filing</guid>
	<link>https://danielpocock.com/en/reform-uk-last-minute-accounts-filing/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/pocock.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;On 25 June 2026,
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt;, the political party,
&lt;a href=&quot;https://search.electoralcommission.org.uk/Api/Accounts/Documents/28357&quot;&gt;
filed accounts for the 2025 calendar year with the Electoral Commission&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; is the only major political party in the
&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
UK&lt;/a&gt; that is also registered as a company at Companies House.&lt;/p&gt;

&lt;p&gt;Consequently, each year, they must file a set of accounts, with an
auditor&#39;s report, at Companies House.  The deadline was today,
30 September 2026.  Why did they file the accounts at the very last
minute and not at the same time they filed with the Electoral
Commission?&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://find-and-update.company-information.service.gov.uk/company/16260766/filing-history&quot;&gt;
Click here to see the filing history and access the other accounts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As explained in
&lt;a href=&quot;https://danielpocock.com/en/reform-uk-auditor-electoral-commission-accounts-companies-house-going-concern-or-not/&quot;&gt;
my previous blog on the subject&lt;/a&gt;, the reports given to Companies House
are slightly different from the reports given to the Electoral Commission.
The Electoral Commission is trying to show the impact of money on
democracy.  The Companies House report aims to give members, investors,
trading partners and employees an image of the organisation&#39;s strength
or weakness.&lt;/p&gt;

&lt;p&gt;The document uploaded to the Electoral Commission in June is a
text-searchable PDF.  The PDF uploaded to Companies House is not
text-searchable.  However, Companies House also has another copy
in iXBRL, which is an XHTML file that is text-searchable in a web
browser.&lt;/p&gt;

&lt;p&gt;At a glance, we can see the numbers are not exactly the same.
For example, the membership revenue in the report to the
Electoral Commission appears to be a bit higher because they used
to collect the money through a different company and then they
subsequently merged the two companies during the 2025 reporting
year.&lt;/p&gt;

&lt;p&gt;Like the report submitted to the Electoral Commission, the report
submitted to Companies House does not mention the potential impact
of the new, backdated restrictions on donations from overseas electors.
If those restrictions are implemented soon, they will have a very
severe impact on
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt;.  It seems odd to me they can completely omit that
from the statement about the company being a going concern
for the next 12 months.&lt;/p&gt;

&lt;p&gt;One of the very significant differences in the Companies House
report submitted today is on the very last page.  It is the
declaration about how they merged the two former companies and
who really has control over the company, which is acting as a
political party but is really a business:&lt;/p&gt;

&lt;blockquote&gt;
&lt;em&gt;&lt;h3&gt;19. Related party transactions&lt;/h3&gt;
&lt;p&gt;On 19 February 2025, the company acquired the entire issued share capital of Reform 2025 Ltd for consideration of £15.&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;

&lt;h3&gt;20. Controlling party&lt;/h3&gt;
&lt;p&gt;The company is limited by guarantee and has no share capital. The company has &lt;b&gt;two members&lt;/b&gt;, who have equal voting rights. &lt;b&gt;Neither member has individual control of the company&lt;/b&gt; and, accordingly, there is no ultimate controlling party.&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;h3&gt;Legal form of entity and country of incorporation&lt;/h3&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;The company is &lt;b&gt;limited by guarantee&lt;/b&gt; and has no share capital. &lt;b&gt;The liability of each member is limited to £1&lt;/b&gt;, being the amount that each member undertakes to contribute to the assets of the company in the event of its winding up. There were two members at the year end.&lt;/p&gt;
&lt;/em&gt;&lt;/blockquote&gt;

&lt;p&gt;Looking at the full list of documents on the Companies House web site,
we can find the
&lt;a href=&quot;https://find-and-update.company-information.service.gov.uk/company/16260766/filing-history/MzQ1NDMwODY0MWFkaXF6a2N4/document?format=pdf&amp;amp;download=0&quot;&gt;
first document filed when the company was created&lt;/a&gt;.  They tell us the
two real members of the company are
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; and
&lt;a href=&quot;https://danielpocock.com/en/zia-yusuf/&quot;&gt;
Zia Yusuf&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Companies &lt;em&gt;limited by guarantee&lt;/em&gt; in the
&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
UK&lt;/a&gt; are a special type of company that is normally used for non-profits
and charities.  In some non-profits, like sporting clubs, every member
is really a member of the company and invited to the annual general meeting.
&lt;/p&gt;

&lt;p&gt;The accounts that
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; has just filed show us they have a two-tier membership structure,
similar to the scandal of the
&lt;a href=&quot;https://danielpocock.com/en/category/fsfe-misfits/&quot;&gt;
FSFE misfits&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;People who &quot;join&quot;
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; and pay £25 per year are not really members like
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; and
&lt;a href=&quot;https://danielpocock.com/en/zia-yusuf/&quot;&gt;
Zia Yusuf&lt;/a&gt; are members in the accounts.&lt;/p&gt;

&lt;p&gt;In
&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
UK&lt;/a&gt; law, the real members,
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; and
&lt;a href=&quot;https://danielpocock.com/en/zia-yusuf/&quot;&gt;
Zia Yusuf&lt;/a&gt;, can choose to change it into a normal shareholder company
at any time they want and then they can sell the shares or pass them to
their children, as long as the articles of association permit that.&lt;/p&gt;

&lt;p&gt;In June 2025,
&lt;a href=&quot;https://www.bbc.com/news/articles/cwyv040rnqzo&quot;&gt;
Zia Yusuf resigned from Reform UK and came back two days later&lt;/a&gt;.
The accounts show us that he resigned from his position on the board
but they do not tell us if he transferred his position as one of the
two controlling members to somebody else.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; claims to have more members than any other political
party in the
&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
UK&lt;/a&gt;.  These accounts tell us their company only has two members,
making it one of the smallest political parties at the same time
as being one of the biggest.&lt;/p&gt;

&lt;p&gt;If the members accept this two-tier structure, does that mean it
really is a
&lt;a href=&quot;https://danielpocock.com/en/category/cult-behaviour/&quot;&gt;
cult&lt;/a&gt;, as we were
&lt;a href=&quot;https://danielpocock.com/en/cults-leak-email-domains-revealed/&quot;&gt;
told by Rupert Lowe&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;When they changed the structure, they told people they were
making it more democratic.  What they really did is they reduced their
risk.  If it fails, they only lose their guarantee, which is £1
each.  If it succeeds, these two people can choose to pivot back to a
shareholder company form, issue shares and sell them on the stock market.&lt;/p&gt;

&lt;p&gt;The other thing they did through this reoganisation is obfuscating the
history of disputes and judgments against the former company.  It looks
like at least one law suit is still progressing against the old company
and it is not clear if the new company structure will be obliged to pay
for it if they lose.&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.gov.uk/hmrc-internal-manuals/economic-crime-supervision-handbook/ecsh52200&quot;&gt;
The UK permits directors, company secretaries and shareholders
to be nominees, in other words, proxies&lt;/a&gt; contracted to obey the
person who really pays them to perform that role.  While
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; and
&lt;a href=&quot;https://danielpocock.com/en/zia-yusuf/&quot;&gt;
Zia Yusuf&lt;/a&gt; are listed publicly as the members who founded the new entity
in February 2025, there is no obligation for them to publicly identify
any transfers of these memberships to other people.  The only thing we
can deduce from the report is that there are currently two members,
the same number of members they had when they created the entity
but not necessarily the same two people.&lt;/p&gt;

&lt;p&gt;Read more about the
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
various judgments in the history of Reform UK Party Limited&lt;/a&gt;.&lt;/p&gt;

&lt;img alt=&quot;Nigel Farage, Adam Richardson, Company&#39;s own candidate&quot; src=&quot;https://danielpocock.com/assets/people/nigel-farage/clacton-nigel-farage-voting-day.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Read more about the
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
various judgments in the history of Reform UK Party Limited&lt;/a&gt;.&lt;/p&gt; </description> 
	<pubDate>Wed, 30 Sep 2026 22:15:00 +0000</pubDate>

</item> 
<item>
	<title>Dirk Eddelbuettel: RcppFastFloat 0.0.6 on CRAN: New Upstream</title>
	<guid>http://dirk.eddelbuettel.com/blog/2026/09/30#rcppfastfloat_0.0.6</guid>
	<link>http://dirk.eddelbuettel.com/blog/2026/09/30#rcppfastfloat_0.0.6</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dirk.png&quot; width=&quot;65&quot; height=&quot;90&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;A new release of &lt;a href=&quot;https://dirk.eddelbuettel.com/code/rcpp.fastfloat.html&quot;&gt;RcppFastFloat&lt;/a&gt;
just arrived on &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt;, and has
been built for &lt;a href=&quot;https://eddelbuettel.github.io/r2u/&quot;&gt;r2u&lt;/a&gt;.
The package wraps &lt;a href=&quot;https://github.com/fastfloat/fast_float&quot;&gt;fast_float&lt;/a&gt;, another
nice library by &lt;a href=&quot;https://lemire.me/en/&quot;&gt;Daniel Lemire&lt;/a&gt;. For
details, see the &lt;a href=&quot;https://arxiv.org/abs/2101.11408&quot;&gt;arXiv
preprint&lt;/a&gt; or &lt;a href=&quot;https://doi.org/10.1002/spe.2984&quot;&gt;published&lt;/a&gt;
paper showing that one can convert character representations of
‘numbers’ into floating point at rates at or exceeding one gigabyte per
second.&lt;/p&gt;
&lt;p&gt;This release updates the underlying &lt;code&gt;fast_float&lt;/code&gt; library
version to the current version 8.3.0, and also updates a number of the
standard packaging details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;changes-in-version-0.0.6-2026-09-29&quot;&gt;Changes in version 0.0.6
(2026-09-29)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Update to upstream release 8.3.0 (Daniel Lemire in &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastfloat/pull/6&quot;&gt;#6&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Standard package maintenace adding README badge, updating URL,
updating continuous integration, and adding an aspell
dictionary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Completed help page for &lt;code&gt;as_double&lt;/code&gt; example with
@return tag&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Courtesy of my &lt;a href=&quot;https://dirk.eddelbuettel.com/cranberries&quot;&gt;CRANberries&lt;/a&gt;, there
is also a diffstat report for &lt;a href=&quot;https://dirk.eddelbuettel.com/cranberries/2026/09/30#RcppFastFloat_0.0.6&quot;&gt;this
release&lt;/a&gt;. For questions, suggestions, or issues please use the &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastfloat/issues&quot;&gt;issue
tracker&lt;/a&gt; at the &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastfloat&quot;&gt;GitHub
repo&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;font-size: 80%; font-style: italic;&quot;&gt;
This post by &lt;a href=&quot;https://dirk.eddelbuettel.com&quot;&gt;Dirk
Eddelbuettel&lt;/a&gt; originated on his &lt;a href=&quot;https://dirk.eddelbuettel.com/blog&quot;&gt;Thinking inside the box&lt;/a&gt;
blog. If you like this or other open-source work I do, you can now &lt;a href=&quot;https://github.com/sponsors/eddelbuettel&quot;&gt;sponsor me at
GitHub&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt; </description> 
	<pubDate>Wed, 30 Sep 2026 21:17:00 +0000</pubDate>

</item> 
<item>
	<title>Daniel Pocock: High Court victory: Nigel Farage is ‘the Company’s own candidate’</title>
	<guid>https://danielpocock.com/en/high-court-victory-nigel-farage-companys-own-candidate</guid>
	<link>https://danielpocock.com/en/high-court-victory-nigel-farage-companys-own-candidate/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/pocock.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;In the sentencing of the late
&lt;a href=&quot;https://danielpocock.com/en/people/cardinal-george-pell/&quot;&gt;
Cardinal George Pell&lt;/a&gt;, it was his defence lawyer
&lt;a href=&quot;https://danielpocock.com/en/people/robert-richter-kc/&quot;&gt;
Robert Richter KC&lt;/a&gt; who argued the Cardinal should receive a
lighter punishment because it was a &quot;plain vanilla&quot; case of abuse.
In fact, when somebody in such a senior position of trust commits
an offence of that nature, it is a lifelong case of psychological torture
for the victims.  That is what makes institutional abuse, such as the
&lt;a href=&quot;https://juristgate.com/en/&quot;&gt;
abuse by jurists&lt;/a&gt; and the
&lt;a href=&quot;https://danielpocock.com/en/category/catholic-abuse/&quot;&gt;
abuse by the Catholic Church&lt;/a&gt; so much worse than other types of
abuse.&lt;/p&gt;

&lt;p&gt;The Cardinal was later acquitted on appeal.  The day I dared to
walk into a Carabinieri post, in
&lt;a href=&quot;https://danielpocock.com/en/category/italy/&quot;&gt;
Italy&lt;/a&gt; and explained the similarities between the way the snobby set
&lt;a href=&quot;https://danielpocock.com/en/jeremy-bicha-debian-edu-teckids-ubuntu-incest-scandal-debconf25/&quot;&gt;
collaborated to protect paedophiles in both the Church &amp;amp; Debian&lt;/a&gt;,
the Cardinal died four hours later.&lt;/p&gt;

&lt;img alt=&quot;Cardinal George Pell, Enrico Zini&quot; src=&quot;https://danielpocock.com/assets/italy-trip.jpg&quot; width=&quot;100%&quot; /&gt;

&lt;p&gt;In my
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
case against Reform UK Party Limited&lt;/a&gt;, I meekly asked them to pay
£5,000, barely 0.1 percent of the controversial £5 million donation,
based on
&lt;a href=&quot;https://danielpocock.com/en/winding-up-petition-served-reform-uk-party-limited/&quot;&gt;
Farage&#39;s promise to pay for the election&lt;/a&gt;.  Instead, I received this
priceless gem from
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Farage&lt;/a&gt;&#39;s own lawyers.
&lt;a href=&quot;https://danielpocock.com/en/people/adam-richardson-4-5/&quot;&gt;
Adam Richardson&lt;/a&gt; from
&lt;a href=&quot;https://danielpocock.com/en/category/4-5-grays-inn-square/&quot;&gt;
4-5 Gray&#39;s Inn Square&lt;/a&gt; has admitted
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; is &quot;&lt;em&gt;the Company&#39;s own candidate&lt;/em&gt;&quot;.  This is one of
those gaffs that may well stand the test of time, like the &quot;plain vanilla&quot;
defense.  I&#39;ve never seen a confession like that in democracy before.  So much
for the promise
&lt;a href=&quot;https://danielpocock.com/en/category/pocock-on-sea/&quot;&gt;
the Clacton-on-Sea by-election&lt;/a&gt; was an opportunity to vote against
&lt;a href=&quot;https://danielpocock.com/en/category/the-establishment/&quot;&gt;
the Establishment&lt;/a&gt;.&lt;/p&gt;

&lt;img alt=&quot;Nigel Farage, Adam Richardson, Company&#39;s own candidate&quot; src=&quot;https://danielpocock.com/assets/people/nigel-farage/companys-own-candidate.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;img alt=&quot;Nigel Farage, Adam Richardson, Company&#39;s own candidate&quot; src=&quot;https://danielpocock.com/assets/people/adam-richardson-4-5/adam-richardson.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Read more about the
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
various judgments in the history of Reform UK Party Limited&lt;/a&gt;.&lt;/p&gt;

&lt;img alt=&quot;Nigel Farage, Adam Richardson, Company&#39;s own candidate&quot; src=&quot;https://danielpocock.com/assets/people/nigel-farage/clacton-nigel-farage-voting-day.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Read more about the
&lt;a href=&quot;https://danielpocock.com/en/category/winding-up-reform-uk/&quot;&gt;
various judgments in the history of Reform UK Party Limited&lt;/a&gt;.&lt;/p&gt; </description> 
	<pubDate>Wed, 30 Sep 2026 19:45:00 +0000</pubDate>

</item> 
<item>
	<title>Dirk Eddelbuettel: myman 0.1.0 on CRAN: New (fabulous !!) Package</title>
	<guid>http://dirk.eddelbuettel.com/blog/2026/09/30#myman_0.1.0</guid>
	<link>http://dirk.eddelbuettel.com/blog/2026/09/30#myman_0.1.0</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dirk.png&quot; width=&quot;65&quot; height=&quot;90&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Thrilled to share that our new package &lt;a href=&quot;https://github.com/eddelbuettel/myman&quot;&gt;myman&lt;/a&gt; reached &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt; a few days ago. The package
offers sixteen hundred ninety four &lt;em&gt;“My man …”&lt;/em&gt; posts by &lt;a href=&quot;https://bsky.app/profile/kevinmkruse.bsky.social&quot;&gt;Kevin Kruse&lt;/a&gt;
made on &lt;a href=&quot;https://bsky.app&quot;&gt;bsky&lt;/a&gt; during the summer of 2026.
Each wave picked at one particular public persona. This package wrapse
these up in the style of packages like &lt;a href=&quot;https://zeileis.codeberg.page/fortunes/&quot;&gt;fortunes&lt;/a&gt; or &lt;a href=&quot;https://github.com/eddelbuettel/gaussfacts&quot;&gt;gaussfacts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A sample usage illustration shows how to extract by pattern:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-1&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(myman)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-2&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;myman&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&quot;maitre&quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-3&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;My man looks like he&lt;span class=&quot;st&quot;&gt;&#39;s inquiring with the maitre&#39;&lt;/span&gt;d about the house curly fries.&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-4&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;sc&quot;&gt;--&lt;/span&gt; about Howard Lutnick on &lt;span class=&quot;dv&quot;&gt;2026-08-28&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-5&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-6&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;My man looks like a maitre&lt;span class=&quot;st&quot;&gt;&#39;d who deeply doubts you have a reservation.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-7&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;     -- about Scott Bessent on 2026-08-31&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-8&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-9&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;My man looks like he&#39;&lt;/span&gt;s asked the maitre&lt;span class=&quot;st&quot;&gt;&#39;d to remove a party of four he finds visually&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-10&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;unpleasant.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-11&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;     -- about Scott Bessent on 2026-08-31&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-12&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-13&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;My man looks like the maitre&#39;&lt;/span&gt;d at a very exclusive restaurant called The Berghof.&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-14&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;sc&quot;&gt;--&lt;/span&gt; about JD Vance on &lt;span class=&quot;dv&quot;&gt;2026-09-13&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-15&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-16&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One can also subset by ‘target’, or simple sample randomly (which is
the default).&lt;/p&gt;
&lt;p&gt;As &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt; review for new
package takes a little longer these days, the GitHub repo was updated
once more with one (eighth !!) wave of posts since the submission was
made. &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt; version 0.1.0
corresponds to the stock of messages from waves one to seven. We will
update the &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt; version shortly
but if you would like more posts &lt;em&gt;right now&lt;/em&gt; consider installing
from the &lt;a href=&quot;https://github.com/eddelbuettel/myman&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We include the full NEWS file since the package was started, this
also includes an entry for the eights wave we will bring to CRAN
soon.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;changes-in-version-0.1.0-2026-09-27&quot;&gt;Changes in version 0.1.0
(2026-09-27)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Initial CRAN version (minus the 0.0.8 changes which were made
while CRAN reviewed the package)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an aspell dictionary to aid DESCRIPTION text&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.8-2026-09-18&quot;&gt;Changes in version 0.0.8
(2026-09-18)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data set now comprises 1694 posts aiming at eight different
&#39;men&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The number of &#39;sample()&#39; object returned can not be set with
&#39;posts&#39;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.7-2026-09-14&quot;&gt;Changes in version 0.0.7
(2026-09-14)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Data set now comprises 1494 posts aiming at seven different
&#39;men&#39;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.6-2026-09-07&quot;&gt;Changes in version 0.0.6
(2026-09-07)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Data set now comprises 1394 posts aiming at six different &#39;men&#39;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.5-2026-09-01&quot;&gt;Changes in version 0.0.5
(2026-09-01)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data set now comprises 1194 posts aiming at five different
&#39;men&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;myman()&lt;/code&gt; function can now now subset by target
permitting more focussed randlom sampling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.4-2026-08-28&quot;&gt;Changes in version 0.0.4
(2026-08-28)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Data set now comprises 1040 posts aiming at four different
&#39;men&#39;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.3-2026-08-19&quot;&gt;Changes in version 0.0.3
(2026-08-19)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data set now comprises 916 posts aiming at three different
&#39;men&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Csv file, processing and display extended to three columns also
showing post creating date (in UTC) and &#39;man&#39;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.2-2026-07-30&quot;&gt;Changes in version 0.0.2
(2026-07-30)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Updated with full week of posts leading to a corpus of 698
posts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added support for simple regular-expression lookup
ability&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;changes-in-version-0.0.1-2026-07-19&quot;&gt;Changes in version 0.0.1
(2026-07-19)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Initial release&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;font-size: 80%; font-style: italic;&quot;&gt;
This post by &lt;a href=&quot;https://dirk.eddelbuettel.com&quot;&gt;Dirk
Eddelbuettel&lt;/a&gt; originated on his &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/&quot;&gt;Thinking inside the box&lt;/a&gt;
blog. If you like this or other open-source work I do, you can &lt;a href=&quot;https://github.com/sponsors/eddelbuettel&quot;&gt;sponsor me at
GitHub&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt; </description> 
	<pubDate>Wed, 30 Sep 2026 15:44:00 +0000</pubDate>

</item> 
<item>
	<title>Gunnar Wolf: The Origins of GPU Computing</title>
	<guid>https://gwolf.org/2026/09/the-origins-of-gpu-computing.html</guid>
	<link>https://gwolf.org/2026/09/the-origins-of-gpu-computing.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/gwolf.png&quot; width=&quot;69&quot; height=&quot;83&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;blockquote&gt;
		 
		   This post is an &lt;em&gt;unpublished&lt;/em&gt; review
		 
		     
		       
		         for &lt;em&gt;&lt;a href=&quot;https://dl.acm.org/doi/full/10.1145/3778248&quot;&gt;The Origins of GPU Computing&lt;/a&gt;&lt;/em&gt;
		       
		     
		     
		   &lt;/blockquote&gt;
		 
		 &lt;p&gt;This article appears in the “Communications of the ACM” magazine as part of
a series devoting to showcasing relevant examples of technologies where
federal funding of academic research have resulted in widely impacting,
clearly identifiable technological advances that have visibly improved –or,
at least, changed– life far beyond the technological arena.&lt;/p&gt;

&lt;p&gt;The road leading from the first parallel computing technologies built
completely for research, through a phase that was preeminently directed at
gaming, and back to leading current GPUs, that are basically massively
parallel supercomputers used for LLM training and inference and other IA
tasks, is far from trivial, and the authors make a good job outlining it in
few pages. The article is written in a clearly divulgatory way, staying as
clear of technical language as possible.&lt;/p&gt;

&lt;p&gt;The authors present three main enabling technologies for current GPU
technologies: Parallel computing, parallel graphics systems, and stream
processing.&lt;/p&gt;

&lt;p&gt;Coming from a technical formation myself, although clearly better grounded
in the software side of Computer Engineering than on the electronics side,
the most interesting “nugget of information” I take is that parallel
computing was born due to the fact that transistor switching consumes very
little energy, whereas communication along wires consumes much more — so
the more simultaneous operations can be carried out on-chip at once, the
less power will be dissipated as heat (and the less time that will be lost
due to data stores and loads).&lt;/p&gt;

&lt;p&gt;Graphics systems are a natural match for parallel systems, as rendering
realistic images basically requires repeating the same blocks of
instructions to a large array of items. Early GPU implementations were
built on fixed-function graphics pipelines, but by the turn of the century,
when nVidia spinned off the research labs at Stanford and started marketing
their product, introducing along the way the &lt;em&gt;Graphical Processing Unit&lt;/em&gt;
term, product, they enabled it to implement the full OpenGL graphics
pipeline on a single chip.&lt;/p&gt;

&lt;p&gt;Stream processing is the arrangement of in-chip electronics so that they
can better exploit producer-consumer locality between stages, in order to
achieve greater arithmetic intensity (this is, a greater
computation-to-bandwidth ratio), decreasing the total number of access to
memory accesses.&lt;/p&gt;

&lt;p&gt;The authors explain in broad terms the described technologies and how they
fit together, and how the technology was transferred from the universities
to the companies that became the most dynamic companies behind today’s top
trending technologies.&lt;/p&gt;

&lt;p&gt;I felt the article to be engaging and easy to read. As a technologist, I
did miss more details — dates when specific advances were made, how some of
the advances joined into further inventions… But I understand the aim of
the “Federal Funding of Academic Research” series’ aim is more towards
outsiders. And, as such, this work very well explains how trillion-dollar
technologies are only the result of decades of funding research ideas.&lt;/p&gt; </description> 
	<pubDate>Tue, 29 Sep 2026 18:55:02 +0000</pubDate>

</item> 
<item>
	<title>Dima Kogan: Lunar terminator paradox</title>
	<guid>https://notes.secretsauce.net/notes/2026/09/27_lunar-terminator-paradox.html</guid>
	<link>http://notes.secretsauce.net/notes/2026/09/27_lunar-terminator-paradox.html</link>
     <description>  &lt;p&gt;
There&#39;s an optical illusion known by names like the &quot;lunar terminator paradox&quot;.
This has much discussion and descriptions online, but none made sense in my
head, so I wrote &lt;a href=&quot;https://github.com/dkogan/moon&quot;&gt;this program&lt;/a&gt; to figure out what was going on. The paradox:
&lt;/p&gt;

&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;The moon is illuminated by the sun
&lt;/li&gt;
&lt;li&gt;After sunset, the sun is below, so we would expect the illuminated portion of
the moon to point down, towards where the sun is
&lt;/li&gt;
&lt;li&gt;This isn&#39;t what always happens!
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
I was camping in the mountains with a friend recently. We were looking up at the
sky, just after the sun has set. The moon was clearly pointing up.
&lt;/p&gt;

&lt;p&gt;
After playing with &lt;a href=&quot;https://github.com/dkogan/moon&quot;&gt;this program&lt;/a&gt;, I have clarity: we&#39;re looking up at the moon
from below. The most pathological case is a full moon. Let&#39;s say the moon is on
the horizon: elevation=0. If we&#39;re looking at this low moon, and the moon is
full, the sun is directly behind us. The moon is fully illuminated, and we see
100% of the moon disc lit up.
&lt;/p&gt;

&lt;p&gt;
Now, what happens if the moon is not at the horizon, but higher up at the sky?
Effectively, the sun is infinitely far away, so the same part of the moon is lit
up. But we&#39;re now looking at the moon from below, and we would see some of the
dark side on the bottom edge. I.e. the moon appears bright at the top, but has a
dark slice missing at the bottom: it points up! Even at sunset.
&lt;/p&gt;

&lt;p&gt;
This is the most clearly weird case. A half-moon has no paradoxical behavior,
and the more full the moon, the more clearly we can observe the bright moon
pointing up despite the sun being down.
&lt;/p&gt;

&lt;p&gt;
I produce two plots. At 3/4-full moon at sunset we look at the moon as it rises
from the horizon all the way up to the zenith:
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;scan-moon-el.svg&quot; src=&quot;https://notes.secretsauce.net/../../../notes/2026/09/27_lunar-terminator-paradox/scan-moon-el.svg&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
If the moon is at the horizon (elevation = 0), we see the expected 3/4-lit disc.
As the moon rises, we see more and more of its bottom, and thus more and more
dark areas show up: It clearly points up at sunset!
&lt;/p&gt;

&lt;p&gt;
We can also move the sun around. Let&#39;s say the moon is 60deg up; let&#39;s move the
sun from new-moon to a full-moon:
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;scan-sun-az.svg&quot; src=&quot;https://notes.secretsauce.net/../../../notes/2026/09/27_lunar-terminator-paradox/scan-sun-az.svg&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
In the darkest configuration, we can still see a lit crescent on the bottom: the
illumination is all on the opposite side, but we can see a slice of the
illuminated back side. As the sun swings around, we see more and more of the
moon. At azimuth = 90deg, we have a half-lit moon. Past that, more and more of
the moon is visible, always pointing up.
&lt;/p&gt;

&lt;p&gt;
This was also a super interesting study of the current state of AI tools. As I
was writing this and debugging, I would talk to Claude and Gemini about how this
worked and what I should be seeing. They were both completely unable to
comprehend this, and would make infinite circular arguments. Clearly they read
some incomplete explanations on the internet (as I have), and lack the reasoning
capability necessary to distill it into something resembling &quot;understanding&quot;.
AGI is not here yet.
&lt;/p&gt; </description> 
	<pubDate>Sun, 27 Sep 2026 21:04:00 +0000</pubDate>

</item> 
<item>
	<title>Dirk Eddelbuettel: #060: Using bubblewrap for R sandboxing</title>
	<guid>http://dirk.eddelbuettel.com/blog/2026/09/27#060_bubblewrap_for_R</guid>
	<link>http://dirk.eddelbuettel.com/blog/2026/09/27#060_bubblewrap_for_R</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dirk.png&quot; width=&quot;65&quot; height=&quot;90&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Welcome to post 60 in the &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/code/r4&quot;&gt;&lt;span class=&quot;math inline&quot;&gt;&lt;em&gt;R&lt;/em&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/span&gt;&lt;/a&gt; series.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/containers/bubblewrap&quot;&gt;bubblewrap&lt;/a&gt; is
a great tool and very suitable for using with an agent harness. It is a
very compelling—and lightweight—alternative to using a full-blown &lt;a href=&quot;https://www.docker.com/&quot;&gt;docker&lt;/a&gt; container as it offers
low-level unprivileged sandboxing on Linux hosts.&lt;/p&gt;
&lt;p&gt;In a nutshell, &lt;a href=&quot;https://github.com/containers/bubblewrap&quot;&gt;bubblewrap&lt;/a&gt; can ‘turn
everything off’ (see &lt;code&gt;unshare-all&lt;/code&gt; below) and allow access
only to selected services and directories (as shown below). This makes
it a very useful tool be used on a main workstation as it can provide a
lower-risk deployment quite easily while taking advantage of the already
installed software stack. I continue to get a lot of value out of &lt;a href=&quot;https://www.docker.com/&quot;&gt;docker&lt;/a&gt;, especially as &lt;a href=&quot;https://eddelbuettel.github.io/r2u&quot;&gt;r2u&lt;/a&gt; makes installing R
package dependencies so trivial. Its slogan ‘easy, fast, reliable: pick
all three’ clearly holds for &lt;a href=&quot;https://eddelbuettel.github.io/r2u&quot;&gt;r2u&lt;/a&gt;. But sometimes &lt;a href=&quot;https://github.com/containers/bubblewrap&quot;&gt;bubblewrap&lt;/a&gt; is
compelling, for example to launch &lt;a href=&quot;https://opencode.ai/&quot;&gt;opencode&lt;/a&gt; (documented for example at the
&lt;a href=&quot;https://inference.debian.net/doc#quick-start-guide&quot;&gt;debian-inference
site&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;When using &lt;a href=&quot;https://www.R-Project.org&quot;&gt;R&lt;/a&gt; we need add more
directories to the example to provide &lt;code&gt;/etc/alternatives&lt;/code&gt;
which is governing &lt;em&gt;inter alia&lt;/em&gt; the LAPACK / BLAS resolution on
Debian / Ubuntu systems; this is now on &lt;a href=&quot;https://inference.debian.net/doc#quick-start-guide&quot;&gt;debian-inference
site&lt;/a&gt; but wasn’t when I first tried it a few days ago ;-) as well as
&lt;code&gt;/etc/R&lt;/code&gt; for config files and possibly
&lt;code&gt;~/.R/Makevars&lt;/code&gt; for compiler settings. With that my current
wrapper is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode sh&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-1&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-2&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-3&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# cf https://inference.debian.net/doc&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-4&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;#    and &#39;curl&#39; command to set bearer code&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-5&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;bwrap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-6&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; /usr /usr &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-7&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--symlink&lt;/span&gt; usr/bin /bin &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-8&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--symlink&lt;/span&gt; usr/lib /lib &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-9&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--symlink&lt;/span&gt; usr/lib64 /lib64 &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-10&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; /etc/ssl /etc/ssl &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-11&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; /etc/resolv.conf /etc/resolv.conf &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-12&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.gitconfig &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.gitconfig &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-13&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.config/opencode &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.config/opencode &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-14&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.cache/opencode &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.cache/opencode &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-15&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.opencode &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.opencode &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-16&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.local/share/opencode &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.local/share/opencode &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-17&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.local/state/opencode &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.local/state/opencode &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-18&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.R/Makevars &lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/.R/Makevars &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-19&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; /etc/R/ /etc/R &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-20&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--ro-bind&lt;/span&gt; /etc/alternatives/ /etc/alternatives &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-21&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--proc&lt;/span&gt; /proc &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-22&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--dev&lt;/span&gt; /dev &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-23&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--tmpfs&lt;/span&gt; /tmp &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-24&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--bind&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-25&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--chdir&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-26&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--unshare-all&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-27&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--share-net&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-28&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;--die-with-parent&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;http://dirk.eddelbuettel.com/blog/index.rss#cb1-29&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  /usr/local/bin/opencode &lt;span class=&quot;st&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$@&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Launched that way we can have agents use R to check packages sources,
builds, and triage for bugs. this works equally well with local models
served via &lt;a href=&quot;https://ollama.com/&quot;&gt;ollama&lt;/a&gt; (and with that a
quick shoutout to &lt;a href=&quot;https://packages.lingfish.net/apt/&quot;&gt;packages.lingfish.net&lt;/a&gt; for
providing an &lt;code&gt;apt&lt;/code&gt; service for &lt;a href=&quot;https://ollama.com/&quot;&gt;ollama&lt;/a&gt;) as it does with the various
cloud-based offerings. So harness away with R!&lt;/p&gt;
&lt;p style=&quot;font-size: 80%; font-style: italic;&quot;&gt;
This post by &lt;a href=&quot;https://dirk.eddelbuettel.com&quot;&gt;Dirk
Eddelbuettel&lt;/a&gt; originated on his &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/&quot;&gt;Thinking inside the box&lt;/a&gt;
blog. If you like this or other open-source work I do, you can now &lt;a href=&quot;https://github.com/sponsors/eddelbuettel&quot;&gt;sponsor me at
GitHub&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt; </description> 
	<pubDate>Sun, 27 Sep 2026 16:02:00 +0000</pubDate>

</item> 
<item>
	<title>Daniel Pocock: Notorious Gem of Tanzania (Wrekin Ruby) &amp; Nigel Farageâ€™s mega-donations</title>
	<guid>https://danielpocock.com/en/gem-of-tanzania-nigel-farage-mega-donations</guid>
	<link>https://danielpocock.com/en/gem-of-tanzania-nigel-farage-mega-donations/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/pocock.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Many people have seen the recent news about
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK party&lt;/a&gt; receiving two donations of £36 million each.
Therefore, it is quite a shock to see the party simultaneously
being subject to a [redacted debt collection].&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
UK&lt;/a&gt; law doesn&#39;t require a contract to be in writing.
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; presents himself as somebody you can have a pint
with.  If somebody agrees to pay for a round of drinks you don&#39;t
ask them to provide a written contract.  Likewise, when
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; and other leaders in his party made promises to
pay election expenses, I felt that was like offering to buy a round
of drinks.  It was a verbal contract.&lt;/p&gt;

&lt;p&gt;The failure to make those payments provided a justification to
begin [redacted].  Does that mean
&lt;a href=&quot;https://danielpocock.com/en/people/nigel-farage/&quot;&gt;
Nigel Farage&lt;/a&gt; can simply pay me the money and exit the [redacted]
procedure?  Maybe not.  [redacted].&lt;/p&gt;

&lt;p&gt;We can find old reports from other
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; legal entities online.
&lt;a href=&quot;https://search.electoralcommission.org.uk/Api/Accounts/Documents/24349&quot;&gt;
Here are the 2021 accounts&lt;/a&gt;.  This is the relevant statement where
the auditor contemplates whether money loaned to the party by
&lt;a href=&quot;https://danielpocock.com/en/people/richard-tice/&quot;&gt;
Richard Tice&lt;/a&gt; could be a risk to solvency:&lt;/p&gt;

&lt;img alt=&quot;Richard Tice, Reform UK, going concern, uncertainty, 2021&quot; src=&quot;https://danielpocock.com/assets/people/richard-tice/2021-material-uncertainty.jpg&quot; width=&quot;100%&quot; /&gt;
&lt;p&gt; &lt;/p&gt;

&lt;blockquote&gt;&lt;em&gt;
&lt;h3&gt;Material uncertainty related to going concern&lt;/h3&gt;
&lt;p&gt;We draw attention to the Balance Sheet which indicates that as at 31 December 2021,
the Party had net liabilities of £849,456.  As stated in the going concern
accounting policy note, these liabilities consist mainly of directors loans from
&lt;a href=&quot;https://danielpocock.com/en/people/richard-tice/&quot;&gt;
Richard Tice&lt;/a&gt; and we have received suitable reassurances from him about the intention
for these to help grow the party in the medium term.&lt;/p&gt;
&lt;/em&gt;&lt;/blockquote&gt;

&lt;p&gt;When the auditor writes their report for the next set of accounts,
they will have to mention a whole range of scandals much bigger than
that loan.&lt;/p&gt;

&lt;p&gt;Remember that most volunteers and donors put in their time and money
and they can not get their time and money back later.  Yet
&lt;a href=&quot;https://danielpocock.com/en/people/richard-tice/&quot;&gt;
Richard Tice&lt;/a&gt; put in his money as a loan, in other words, when
other people contribute money, he gets his money back.&lt;/p&gt;

&lt;p&gt;The existence of loans like this helps understand directors&#39;
willingness to accept donations that other parties might
not touch with a ten foot pole.&lt;/p&gt;

&lt;p&gt;Notice that
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt; announced the mega donations just two weeks before the deadline for
&lt;a href=&quot;https://danielpocock.com/en/reform-uk-auditor-electoral-commission-accounts-companies-house-going-concern-or-not/&quot;&gt;
the accounts and auditor&#39;s report&lt;/a&gt;.  Hence my curiosity about whether
the publicity about these donations was meant to either sway the
auditor or distract the public from concerns the auditor will express
in the published report.&lt;/p&gt;

&lt;p&gt;We saw the same thing with the notorious &lt;em&gt;Gem of Tanzania&lt;/em&gt;.
By coincidence, in November 2025, shortly before the end of
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt;&#39;s first accounting year, the International Gem Society
&lt;a href=&quot;https://www.gemsociety.org/news/2025/11/03/wrekin-ruby/&quot;&gt;
published a detailed history of the scandal&lt;/a&gt;.  News reports claim
the gem was worth little more than £100.  Nonetheless,
&lt;a href=&quot;https://danielpocock.com/en/category/wrekin-construction/&quot;&gt;
Wrekin Construction&lt;/a&gt; listed it on their balance sheet as an asset
worth £11 million.&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;p&gt;When I saw the news about these mega-donations, I felt déjà-vu.
If it sounds too good to be true, maybe it is.&lt;/p&gt;

&lt;p&gt;Sub-contractors and suppliers to
&lt;a href=&quot;https://danielpocock.com/en/category/wrekin-construction/&quot;&gt;
Wrekin Construction&lt;/a&gt; felt they could give the company favorable
credit terms because the balance sheet filed at Companies House
looked extremely healthy.  Some of the suppliers purchased
&lt;a href=&quot;https://en.wikipedia.org/wiki/Trade_credit_insurance&quot;&gt;
trade credit insurance&lt;/a&gt; and when
&lt;a href=&quot;https://danielpocock.com/en/category/wrekin-construction/&quot;&gt;
Wrekin Construction&lt;/a&gt; went bust, the insurance companies had to
reimburse the suppliers who were not paid.&lt;/p&gt;

&lt;p&gt;When people see these figures in the accounting documents
and news stories about
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt;, they may be fooled to be overoptimistic, in the short
term, about
&lt;a href=&quot;https://danielpocock.com/en/category/reform-uk/&quot;&gt;
Reform UK&lt;/a&gt;&#39;s future prospects.&lt;/p&gt;

&lt;p&gt;The new legislation going through the
&lt;a href=&quot;https://danielpocock.com/en/category/uk/&quot;&gt;
UK&lt;/a&gt; parliament tells us these donations will be converted to loans.
The party will be obliged to repay the money within 30 days.&lt;/p&gt;

&lt;p&gt;The directors have known about this new reality since 25 March 2026
but their words and actions suggest they are being stubborn and
behaving like petulant teenagers.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://danielpocock.com/en/category/cult-behaviour/&quot;&gt;
Read more research on cult behaviour&lt;/a&gt;&lt;/p&gt; </description> 
	<pubDate>Sun, 27 Sep 2026 15:00:00 +0000</pubDate>

</item> 
<item>
	<title>Russ Allbery: Review: Ode to the Half-Broken</title>
	<guid>https://www.eyrie.org/~eagle/reviews/books/0-7564-2013-X.html</guid>
	<link>https://www.eyrie.org/~eagle/reviews/books/0-7564-2013-X.html</link>
     <description>  &lt;p&gt;Review: &lt;cite&gt;Ode to the Half-Broken&lt;/cite&gt;, by Suzanne Palmer&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;&lt;tr&gt;
    &lt;td&gt;Publisher:&lt;/td&gt;
    &lt;td&gt;DAW&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Copyright:&lt;/td&gt;
    &lt;td&gt;May 2026&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;ISBN:&lt;/td&gt;
    &lt;td&gt;0-7564-2013-X&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Format:&lt;/td&gt;
    &lt;td&gt;Kindle&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Pages:&lt;/td&gt;
    &lt;td&gt;441&lt;/td&gt;
  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;
&lt;cite&gt;Ode to the Half-Broken&lt;/cite&gt; is a standalone post-apocalyptic (sort of)
science fiction novel.
&lt;/p&gt;

&lt;p&gt;
As this novel opens, the unnamed first-person protagonist is waking up in
a bathtub in an abandoned building. They are covered in electromagnets and
missing one leg.
&lt;/p&gt;

&lt;p&gt;
Waking up involved a secure reboot from a protected core kernel, so it is
immediately obvious that the protagonist is a robot. That also explains
the electromagnets, which interfere with their ability to control their
body. Or they would, if the protagonist didn&#39;t have long-dormant combat
routines available to deploy EM shielding and free themselves from the
bathtub. There are no immediate answers to why someone embedded a virus in
the data attached to a scientific paper on ants, an act so precisely
targeted that it had to be personal. Or what happened to their leg.
&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;
    &quot;There are a number of electromagnets in the next room,&quot; I say. I
    point. &quot;Behind that wall with all the holes in it.&quot;
&lt;/p&gt;

&lt;p&gt;
    &quot;Those are big holes. And fresh, too,&quot; the dog says. &quot;I wonder what
    made them.&quot;
&lt;/p&gt;

&lt;p&gt;
    &quot;Electromagnets experiencing sudden velocity.&quot;
&lt;/p&gt;

&lt;p&gt;
    The dog gives another of its short barks, and I am more convinced now
    it is laughing, though I was not attempting to be funny.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;
&lt;cite&gt;Ode to the Half-Broken&lt;/cite&gt; has a classic science fiction beginning:
&lt;i&gt;in medias res&lt;/i&gt; in a future science fiction version of Earth where
nothing is immediately explained, leaving the reader to work out the date
and the setting. Helping us out is the protagonist, who is neither chatty
nor very sociable with other characters but keeps up an analytical
monologue about the world as they narrate events.
&lt;/p&gt;

&lt;p&gt;
We are some decades into a grim future. The United States has largely
collapsed. Large parts of New York City are dangerous to humans due to
disease and radiation. Neither of those hazards bother the large number of
sentient robots; their scarcity, and therefore economy, is instead based
on power. Robots that control solar power stations act as low-level mob
bosses, trading power for information or labor.
&lt;/p&gt;

&lt;p&gt;
Our protagonist doesn&#39;t want to care about any of this. They retreated
from the world long ago for a solitary life in the former New York
Botanical Gardens studying ants. But they need a new leg and the best
robot repair person nearby is a human woman outside of the city, so they
reluctantly head in that direction, accompanied somewhat surprisingly by a
cyborg dog.
&lt;/p&gt;

&lt;p&gt;
The typical science fiction apocalypse is caused by something specific.
Classically, that event is a nuclear war, but writers found various
alternatives before, during, and after the Cold War era:
&lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/1-931520-03-8.html&quot;&gt;alien invasions&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/The_Day_of_the_Triffids&quot;&gt;meteor
showers&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/The_Stand&quot;&gt;plagues&lt;/a&gt;,
&lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-316-26233-1.html&quot;&gt;sea level rise&lt;/a&gt;, and &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/1-59780-158-5.html&quot;&gt;peak oil and general environmental collapse&lt;/a&gt;, among many others. Less
common is a post-apocalyptic novel where the collapse comes from multiple
overlapping crises and accumulating failures, from a general failure to
meet what Adam Tooze and others call
&lt;a href=&quot;https://en.wikipedia.org/wiki/Polycrisis&quot;&gt;polycrisis&lt;/a&gt;. The first
time I encountered that style of post-apocalyptic story was in Octavia
Butler&#39;s &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-446-60197-7.html&quot;&gt;&lt;cite&gt;Parable of the Sower&lt;/cite&gt;&lt;/a&gt;. It was
one of the choices that made (and still makes) that book feel so
chillingly realistic.
&lt;/p&gt;

&lt;p&gt;
The world background in &lt;cite&gt;Ode to the Half-Broken&lt;/cite&gt; is shaped by that
sort of polycrisis collapse. There is no one reason why New York City is a
dangerous, irradiated ruin and society has collapsed into isolated and
sometimes warring factions. It is not runaway artificial intelligence, or
at least not directly; sentient robots were a late-stage innovation of the
collapsing US civilization and a tool and accelerator of its many wars,
but they were not the cause and may be a critical ingredient in building
some functional replacement. Instead, society fell apart because we failed
to address any of the growing problems and then turned on each other in
the resulting ruins. The reader gets an idiosyncratic view of that
collapse in flashback chapters intermixed with the main narrative of the
initially unnamed robot protagonist, flashbacks told from the perspective
of the man who invented the key component for robot sentience. As you
would expect, those two narratives are linked. The reader will not
discover how they are linked until late in the story.
&lt;/p&gt;

&lt;p&gt;
This book could have been extremely depressing. It is not, which says a
great deal about Palmer&#39;s skill in telling it. The clinical distance of
the protagonist in the early chapters helps considerably: They have
rejected involvement in this world and therefore can describe it in
detached, factual terms, aided by the tendency of most robots in this
story to be slightly more precise, logical, and verbose than the human
characters. But as the protagonist&#39;s clinical distance fades, as it must
to allow the story&#39;s emotional stakes to rise, Palmer fills this book with
moments of beauty and hope. A former nuclear submarine that has become the
mind of a subway car is a key early ally. A collective has turned the
Hudson Bridge into a thriving if chaotic community. Self-regulating
enclaves of humans and robots are working together to try to build a
livable world. Robots oversee pollinator swarms that are attempting to
restore plant life, for no reason other than that they like order and
stability and see this as a way of restoring both. This is a grim,
post-apocalyptic world that does not dwell on either the grimness or the
apocalypse. It is instead full of small moments of hope, collaboration,
and personal connection.
&lt;/p&gt;

&lt;p&gt;
This is a story with villains, danger, pain, and risk. Despite the similar
keywords and cover aesthetics, it bears little resemblance to Becky
Chambers&#39;s philosophical &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/1-250-23622-3.html&quot;&gt;Monk and Robot series&lt;/a&gt;.
It is not, in any definition of the term, cozy; it&#39;s a post-apocalyptic
adventure story about a robot and a dog making their way through a ruined
civilization and fighting people who are trying to build something even
worse on the rubble. But it&#39;s also charming and oddly happy. There are
strong found-family vibes in the way that a party coalesces around the
protagonist and eventually gives them a name, there is the quiet happiness
of seeing a grumpy misanthrope slowly come out of their protective shell,
and the rail mechs are an absolute delight.
&lt;/p&gt;

&lt;p&gt;
Like a lot of stories of happy small-group anarchism, I didn&#39;t entirely
believe the politics and have some qualms about the realism of the ending,
although perhaps I should strive to be as optimistic as Palmer writes. The
somewhat dry and fussily precise first-person narration will also not be
to everyone&#39;s taste; it worked for me by the end of the book, but it took
a bit of reading to get used to it. But those quibbles aside, this was
quietly lovely. It&#39;s a satisfying science fiction adventure story in a
world with disturbing parallels to the one we&#39;re living in, but which uses
those parallels to focus on small-scale collective efforts to build
something better. And all the small details of the world-building are
delightful: the different tiers of robots and their odd behaviors, the
machine sense of purpose, even the mix of suspicion and generosity. The
plot has large-scale implications, but it was the human-level details that
charmed me.
&lt;/p&gt;

&lt;p&gt;
I still want &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-7564-1888-7.html&quot;&gt;another Fergus novel&lt;/a&gt;, but this was
a highly successful foray outside of that series. Palmer has won two Hugos
for her novellas, so I can&#39;t really say she&#39;s overlooked, but her novels
aren&#39;t getting anywhere near the attention they deserve. Highly
recommended.
&lt;/p&gt;

&lt;p&gt;
There is plenty of world-building room here for a sequel, but &lt;cite&gt;Ode to
the Half-Broken&lt;/cite&gt; reaches a satisfying standalone conclusion. So far as I
know, no sequel is currently planned.
&lt;/p&gt;

&lt;p&gt;Rating: 8 out of 10&lt;/p&gt; </description> 
	<pubDate>Sun, 27 Sep 2026 02:57:00 +0000</pubDate>

</item> 
<item>
	<title>Dirk Eddelbuettel: RcppFastAD 0.0.5 on CRAN: Maintenance</title>
	<guid>http://dirk.eddelbuettel.com/blog/2026/09/24#rcppfastad_0.0.5</guid>
	<link>http://dirk.eddelbuettel.com/blog/2026/09/24#rcppfastad_0.0.5</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dirk.png&quot; width=&quot;65&quot; height=&quot;90&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;A new release 0.0.5 of the &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;RcppFastAD&lt;/a&gt; package
is now on &lt;a href=&quot;https://cran.r-project.org&quot;&gt;CRAN&lt;/a&gt;, has been built
for &lt;a href=&quot;https://eddelbuettel.github.io/r2u/&quot;&gt;r2u&lt;/a&gt;, and updated
at &lt;a href=&quot;https://eddelbuettel.r-universe.dev/RcppFastAD&quot;&gt;r-universe&lt;/a&gt;.
This comes (to the day) two years after the preceding 0.0.4 release.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;RcppFastAD&lt;/a&gt;
wraps the &lt;a href=&quot;https://github.com/JamesYang007/FastAD&quot;&gt;FastAD&lt;/a&gt;
header-only C++ library by &lt;a href=&quot;https://github.com/JamesYang007&quot;&gt;James&lt;/a&gt; which provides a C++
implementation of both forward and reverse mode of automatic
differentiation. It offers an easy-to-use header library that is both
lightweight and performant. With a little of bit of &lt;a href=&quot;https://www.rcpp.org&quot;&gt;Rcpp&lt;/a&gt; glue, it is also easy to use from R
in simple C++ applications. This release updates the continuous
integration setup as one does, adds a local configuration helper to
quieten compilation (described also in &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/2026/07/27#057_conditionally_quieten_compilers&quot;&gt;this
blog post&lt;/a&gt;). It also adds a defensive setting for &lt;code&gt;g++&lt;/code&gt;:
Under recent &lt;code&gt;g++&lt;/code&gt; versions and optimisation at least the -O3
level, segfaults are seen as &lt;em&gt;something&lt;/em&gt; is not quite right with
(temporary) “views” of Eigen objects in code generated by this versions.
Others are fine, as is &lt;code&gt;clang++&lt;/code&gt;. We have not gotten to the
bottom of it, but setting &lt;code&gt;-g0&lt;/code&gt; seems to ensure that builds
generally work.&lt;/p&gt;
&lt;p&gt;The NEWS file for this release follows.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;changes-in-version-0.0.5-2026-09-24&quot;&gt;Changes in version 0.0.5
(2026-09-24)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Several routine updates to continuous integration have been
made&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local builds (where a &lt;code&gt;.git/&lt;/code&gt; directory is seen) now
append silencing compiler option that CRAN would object to&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Given recent issues with &lt;code&gt;g++&lt;/code&gt; under optimization,
debugging is turned off by default.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Courtesy of my &lt;a href=&quot;https://dirk.eddelbuettel.com/cranberries/&quot;&gt;CRANberries&lt;/a&gt;, there
is also a diffstat report for the &lt;a href=&quot;https://dirk.eddelbuettel.com/cranberries/2026/09/24#RcppFastAD_0.0.5&quot;&gt;most
recent release&lt;/a&gt;. More information is available at the &lt;a href=&quot;https://github.com/eddelbuettel/rcppfastad&quot;&gt;repository&lt;/a&gt; or the
&lt;a href=&quot;https://dirk.eddelbuettel.com/code/rcpp.fastad.html&quot;&gt;package
page&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;font-size: 80%; font-style: italic;&quot;&gt;
This post by &lt;a href=&quot;https://dirk.eddelbuettel.com&quot;&gt;Dirk
Eddelbuettel&lt;/a&gt; originated on his &lt;a href=&quot;https://dirk.eddelbuettel.com/blog/&quot;&gt;Thinking inside the box&lt;/a&gt;
blog. If you like this or other open-source work I do, you can now &lt;a href=&quot;https://github.com/sponsors/eddelbuettel&quot;&gt;sponsor me at
GitHub&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt; </description> 
	<pubDate>Thu, 24 Sep 2026 19:13:00 +0000</pubDate>

</item> 
<item>
	<title>Russell Coker: Links September 2026</title>
	<guid>https://etbe.coker.com.au/?p=6302</guid>
	<link>https://etbe.coker.com.au/2026/09/24/links-september-2026/</link>
     <description>  &lt;p&gt;&lt;a href=&quot;https://arcan-fe.com/2022/04/02/the-day-of-a-new-command-line-interface-shell/&quot;&gt;Bjorn Stahl of the Arcan project wrote an insightful blog post The Day of a new Command-Line Interface: Shell [1]&lt;/a&gt;. He does a really good job of identifying problems and strategies for dealing with them, the UI of the results isn’t suitable to what I do though.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fzakaria.com/2026/08/23/your-executable-is-a-sqlite-database&quot;&gt;Using sqlite as an executable format (replacement for ELF) is one of the wildest ideas I’ve seen in a while, it might actually have some good use cases too [2]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://longnow.org/ideas/space-dead/&quot;&gt;Andrew Dana Hudson wrote an interesting LongNow article about SciFi’s focus on space travel when it seems unlikely [3]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://thedriven.io/2026/07/24/a-mining-campaign-dressed-in-an-akubra-the-hands-off-our-fuel-petition-is-not-about-farmers/&quot;&gt;TheDriven has an informative article about the “Hands Off Our Fuel” astroturf campaign that uses farmers as the face of an attempt to give tax exemptions to mining companies [4]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://theconversation.com/china-has-cracked-down-on-ai-companions-what-can-we-learn-from-this-287976&quot;&gt;The Conversation has an interesting article about the new Chinese regulations restricting access to AI systems to prevent emotional dependence and prevent minors from having virtual partners or relatives [5]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hashman.ca/managing-venvs/&quot;&gt;Elana Hashman wrote an informative blog post about Python virtualenvs, has useful information for people who aren’t Python experts and just need to get stuff done [6]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dreamstation.systems/personal/ntppool.html&quot;&gt;We need more systems in the NTP pool, I would consider doing this if I had a server with an IP address that won’t change and no risk of bandwidth throttling [7]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pluralistic.net/2026/08/01/dare-snot/#i-will-fucking-piledrive-you-if-you-mention-ai-again&quot;&gt;Cory Doctorow has some interesting thoughts on the CEO fetish for “AI” even though it is almost never doing any good [8]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.theguardian.com/lifeandstyle/2026/aug/05/journalist-taking-on-tech-fascists-silicon-valley&quot;&gt;Steve Rose wrote an insightful article for The Guardian about the tech fascists of Silicon Valley [9]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.theguardian.com/australia-news/2026/sep/10/jacqui-lambie-says-pauline-hanson-a-bloody-coward-after-one-nation-cartoon-calling-andrew-hastie-a-traitor-ntwnfb&quot;&gt;Jacqui Lambie calls Pauline Hanson an “angry little woman” and a “bloody coward”, One Nation hate the rule of law [10]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://theconversation.com/regime-change-might-be-2026s-nonfiction-bestseller-heres-why-its-essential-chilling-reading-288382&quot;&gt;The Conversation has an interesting article about Regime Change, the book about Trump by Maggie Haberman and Jonathan Swan [11]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://freedium-mirror.cfd/https://medium.com/@elvirabary/law-is-for-the-weak-why-russians-have-no-respect-for-the-law-bd590d3ef157&quot;&gt;Elvira Barry wrote an insightful article about the many failures of the Russian legal system, it’s interesting to note that ALL those failures match things that the Trump regime is doing [12]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=y50uWvxGb-A&quot;&gt;Pyotr Kurzin – Geopolitics YouTube channel has an interesting interview about “continental” vs “maritime” powers in the context of what the US and Russia are doing [13]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BXLGV0Sj0n8&quot;&gt;Maxinomica has an interesting video about how China obtained a monopoly on rare earth metals and what happens next [14]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://anarc.at/blog/2026-08-18-people-vs-ai-overlords/&quot;&gt;Anarcat wrote an insightful blog post The people vs the AI overlords about the problems that “AI” software development is bringing [15]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://changelog.complete.org/archives/44740-ai-in-debian-the-vote-proposals-and-nuance&quot;&gt;John Goerzen wrote an interesting blog post discussing the issues related to LLM use in FOSS projects [16]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cybernews.com/security/android-oem-vulnerability-unprivileged-app-root/&quot;&gt;Cybernews has an article about an exploit for Samsung, Xiaomi, Oppo, and OnePlus phones due to bad OEM kernel drivers and bad OEM API proxies, no company should release devices with proprietry drivers [17]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forwardfuture.com/newsletter/originals/gina-raimondo-says-basic-income-would-end-america-her-new-billion-dollar-org-is-how-she-plans-to-sto&quot;&gt;Scott Santens wrote an insightful article about how retraining fails laid-off workers and why UBI is needed when workers get replaced by LLMs [18]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://libroot.org/posts/what-happened-to-the-snowden-archive&quot;&gt;libroot has some information on the Snowden archive and why so little of it has been used by journalists, we need more answers about this [19]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://drewdevault.com/weird-guys/&quot;&gt;Drew Devault’s list of Weird little guys of FOSS is interesting history about some people who are best avoided [20]&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1]&lt;a href=&quot;https://arcan-fe.com/2022/04/02/the-day-of-a-new-command-line-interface-shell/&quot;&gt; https://tinyurl.com/ydye29ta&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2]&lt;a href=&quot;https://fzakaria.com/2026/08/23/your-executable-is-a-sqlite-database&quot;&gt; https://tinyurl.com/26223e79&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3]&lt;a href=&quot;https://longnow.org/ideas/space-dead/&quot;&gt; https://longnow.org/ideas/space-dead/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[4]&lt;a href=&quot;https://thedriven.io/2026/07/24/a-mining-campaign-dressed-in-an-akubra-the-hands-off-our-fuel-petition-is-not-about-farmers/&quot;&gt; https://tinyurl.com/287rktuz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[5]&lt;a href=&quot;https://theconversation.com/china-has-cracked-down-on-ai-companions-what-can-we-learn-from-this-287976&quot;&gt; https://tinyurl.com/25a9mag3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[6]&lt;a href=&quot;https://hashman.ca/managing-venvs/&quot;&gt; https://hashman.ca/managing-venvs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[7]&lt;a href=&quot;https://dreamstation.systems/personal/ntppool.html&quot;&gt; https://dreamstation.systems/personal/ntppool.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[8]&lt;a href=&quot;https://pluralistic.net/2026/08/01/dare-snot/#i-will-fucking-piledrive-you-if-you-mention-ai-again&quot;&gt; https://tinyurl.com/2bzwm5d6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[9]&lt;a href=&quot;https://www.theguardian.com/lifeandstyle/2026/aug/05/journalist-taking-on-tech-fascists-silicon-valley&quot;&gt; https://tinyurl.com/25bj88ss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[10]&lt;a href=&quot;https://www.theguardian.com/australia-news/2026/sep/10/jacqui-lambie-says-pauline-hanson-a-bloody-coward-after-one-nation-cartoon-calling-andrew-hastie-a-traitor-ntwnfb&quot;&gt; https://tinyurl.com/2ywkupwv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[11]&lt;a href=&quot;https://theconversation.com/regime-change-might-be-2026s-nonfiction-bestseller-heres-why-its-essential-chilling-reading-288382&quot;&gt; https://tinyurl.com/257umlg6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[12]&lt;a href=&quot;https://freedium-mirror.cfd/https://medium.com/@elvirabary/law-is-for-the-weak-why-russians-have-no-respect-for-the-law-bd590d3ef157&quot;&gt; https://tinyurl.com/2cjyev9l&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[13]&lt;a href=&quot;https://www.youtube.com/watch?v=y50uWvxGb-A&quot;&gt; https://www.youtube.com/watch?v=y50uWvxGb-A&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[14]&lt;a href=&quot;https://www.youtube.com/watch?v=BXLGV0Sj0n8&quot;&gt; https://www.youtube.com/watch?v=BXLGV0Sj0n8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[15]&lt;a href=&quot;https://anarc.at/blog/2026-08-18-people-vs-ai-overlords/&quot;&gt; https://anarc.at/blog/2026-08-18-people-vs-ai-overlords/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[16]&lt;a href=&quot;https://changelog.complete.org/archives/44740-ai-in-debian-the-vote-proposals-and-nuance&quot;&gt; https://tinyurl.com/2a8pzj8j&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[17]&lt;a href=&quot;https://cybernews.com/security/android-oem-vulnerability-unprivileged-app-root/&quot;&gt; https://tinyurl.com/249oafcy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[18]&lt;a href=&quot;https://forwardfuture.com/newsletter/originals/gina-raimondo-says-basic-income-would-end-america-her-new-billion-dollar-org-is-how-she-plans-to-sto&quot;&gt; https://tinyurl.com/28f5gdjv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[19]&lt;a href=&quot;https://libroot.org/posts/what-happened-to-the-snowden-archive&quot;&gt; https://tinyurl.com/2cv3v9e7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[20]&lt;a href=&quot;https://drewdevault.com/weird-guys/&quot;&gt; https://drewdevault.com/weird-guys/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;yarpp yarpp-related yarpp-related-rss yarpp-template-list&quot;&gt;

&lt;p&gt;Related posts:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2025/03/31/links-march-2025/&quot; rel=&quot;bookmark&quot; title=&quot;Links March 2025&quot;&gt;Links March 2025&lt;/a&gt; &lt;small&gt;Anarcat’s review of Fish is interesting and shows some benefits...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2026/02/17/links-february-2026/&quot; rel=&quot;bookmark&quot; title=&quot;Links February 2026&quot;&gt;Links February 2026&lt;/a&gt; &lt;small&gt;Charles Stross has a good theory of why “AI” is...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2024/09/30/links-september-2024/&quot; rel=&quot;bookmark&quot; title=&quot;Links September 2024&quot;&gt;Links September 2024&lt;/a&gt; &lt;small&gt;CNA Insider has an insightful documentary series about Chinese illegal...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Thu, 24 Sep 2026 10:33:22 +0000</pubDate>

</item> 
<item>
	<title>Mike Gabriel: Looking for Golang + Fullstack Developer with interest in Civic Tech</title>
	<guid>160 at https://sunweavers.net/blog</guid>
	<link>https://sunweavers.net/blog/node/160</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/sunweaver.png&quot; width=&quot;82&quot; height=&quot;82&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;h3&gt;Who?&lt;/h3&gt;

&lt;p&gt;Fre(i)e Software GmbH is looking for a senior Golang + fullstack developer who can handwrite code and act as meticulous code review partner for another senior developer in the company.&lt;/p&gt;

&lt;h3&gt;What?&lt;/h3&gt;

&lt;p&gt;Most of your work would result in Open Source contributions to the Voxit project [1], an online civic tech tool for digital participation.&lt;/p&gt;

&lt;h3&gt;How and Where?&lt;/h3&gt;

&lt;p&gt;The work can either be delivered on project agreement base via freelancing or via employment (option only available to developers resident in Germany, Austria or Poland).&lt;/p&gt;

&lt;h3&gt;What next?&lt;/h3&gt;

&lt;p&gt;If you are interested, please get in touch and provide your hourly rate to us and your average hours of availability per week.&lt;/p&gt;

&lt;p&gt;[1] &lt;a href=&quot;https://gitlab.com/voxit/&quot; title=&quot;https://gitlab.com/voxit/&quot;&gt;https://gitlab.com/voxit/&lt;/a&gt;&lt;/p&gt; </description> 
	<pubDate>Wed, 23 Sep 2026 20:16:37 +0000</pubDate>

</item> 
<item>
	<title>Vincent Bernat: Bot-free self-hosted analytics with GoatCounter on NixOS</title>
	<guid>http://www.luffy.cx/en/blog/2026-goatcounter.html</guid>
	<link>https://vincent.bernat.ch/en/blog/2026-goatcounter</link>
     <description>  &lt;p&gt;Inâ€¯2016, I &lt;a href=&quot;https://github.com/vincentbernat/vincent.bernat.ch/commit/4c3be65404031bf6638c1ea3d891a3ea58e0a0fc&quot; title=&quot;layout: remove Google Analytics&quot;&gt;removed Google Analytics&lt;/a&gt; from this blog to avoid being
complicit in feeding the biggest machine for harvesting personal data. Instead,
I relied on &lt;a href=&quot;https://goaccess.io/&quot; title=&quot;GoAccess: Visual Web Log Analyzer&quot;&gt;GoAccess&lt;/a&gt; to analyze my server logs.&lt;sup id=&quot;fnref:scrub&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:scrub&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; For the past couple
of years, the statistics have made no sense, despite my attempts to filter bots:
&lt;a href=&quot;https://herman.bearblog.dev/the-great-scrape/&quot; title=&quot;The Great Scrape&quot;&gt;AI scrapers&lt;/a&gt; inflate the number of visitors to around 2,000 per
day. Eventually, I settled on &lt;a href=&quot;https://www.goatcounter.com/&quot; title=&quot;GoatCounter: open source web analytics&quot;&gt;GoatCounter&lt;/a&gt;, an open-source, privacy-friendly
web analytics platform. I replaced the JavaScript client to filter bots more
aggressively and added a CSS fallback. To improve reliability, I implemented a
local proxy running on each of the five web servers serving this blog. The rest
of this post details how these pieces fit together and how I deploy them on
NixOS. â�„ï¸�&lt;/p&gt;
&lt;div class=&quot;toc&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#why-goatcounter&quot;&gt;Why GoatCounter?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#custom-javascript-client&quot;&gt;Custom JavaScript client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#local-proxy&quot;&gt;Local proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#deploying-on-nixos&quot;&gt;Deploying on NixOS&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#deploying-applications-in-containers&quot;&gt;Deploying applications in containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#goatcounter-server&quot;&gt;GoatCounter server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#goatcounter-proxy&quot;&gt;GoatCounter proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vincent.bernat.ch#backup-of-the-sqlite-database-with-litestream&quot;&gt;Backup of the SQLite database with Litestream&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;why-goatcounter&quot;&gt;Why GoatCounter?&lt;/h1&gt;
&lt;p&gt;GoatCounter does not &lt;a href=&quot;https://www.goatcounter.com/help/sessions#technical-details-11181&quot; title=&quot;GoatCounter documentation: sessions&quot;&gt;collect personal data&lt;/a&gt;: instead of storing the readerâ€™s
IP address or relying on cookies, it creates a session identifier valid for 8
hours from the user agent and the IP address. Its feature set is modest but
sufficient for a blog. If you want to look at the interface, GoatCounterâ€™s
author runs a &lt;a href=&quot;https://stats.arp242.net&quot; title=&quot;Analytics for www.arp242.net&quot;&gt;public instance&lt;/a&gt; for &lt;a href=&quot;https://www.arp242.net&quot; title=&quot;Personal website of Martin Tournoij&quot;&gt;his site&lt;/a&gt;. A hosted
version lets you try it before running your own instance. With a single binary
and an SQLite database, GoatCounter is one of the lightest self-hosted
solutions. Privacy-friendly alternatives, in increasing order of complexity,
include &lt;a href=&quot;https://umami.is/&quot; title=&quot;Umami: Privacy-First Analytics Platform&quot;&gt;Umami&lt;/a&gt;, &lt;a href=&quot;https://plausible.io/&quot; title=&quot;Plausible Analytics: Simple, privacy-friendly Google Analytics alternative&quot;&gt;Plausible&lt;/a&gt;, and &lt;a href=&quot;https://rybbit.com/&quot; title=&quot;Rybbit: Cookieless Google Analytics Replacement&quot;&gt;Rybbit&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&quot;lf-fullbleed&quot;&gt;&lt;div class=&quot;lf-media-outer&quot; style=&quot;width: 889px;&quot;&gt;&lt;span class=&quot;lf-media-inner&quot;&gt;&lt;img alt=&quot;GoatCounter dashboard showing some statistics from my blog, including an article on the spanning tree protocol with 1,224 views for the past week, the referrers, and the breakdown of browsers (52% Chrome, 32% Firefox, with 16% for Firefoxâ€¯155 and 6% for Firefoxâ€¯156)&quot; class=&quot;lf-media lf-opaque&quot; height=&quot;861&quot; src=&quot;https://d2pzklc15kok91.cloudfront.net/images/goatcounter@1x.66acd322278cc7.png&quot; width=&quot;889&quot; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;h1 id=&quot;custom-javascript-client&quot;&gt;Custom JavaScript client&lt;/h1&gt;
&lt;p&gt;GoatCounter includes a &lt;a href=&quot;https://github.com/arp242/goatcounter/blob/main/public/count.js&quot; title=&quot;GoatCounter&#39;s JavaScript client&quot;&gt;small JavaScript client&lt;/a&gt;â€”2,189 bytes minified and
gzipped. It ships some features I donâ€™t use: a visitor counter, tracking clicks,
configurable settings, etc. I replace it with this function to register a hit:&lt;/p&gt;
&lt;div class=&quot;language-javascript codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;URLSearchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pathname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;referrer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;documentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clientWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rnd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`/count?&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keepalive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To filter bots,&lt;sup id=&quot;fnref:bot-filter&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:bot-filter&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; I go the extra mile by requiring a user
interactionâ€”an idea I stole from &lt;a href=&quot;https://bearblog.dev/&quot; title=&quot;Bear Blog&quot;&gt;Bear Blog&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;language-javascript codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sendHit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sendHit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;touchmove&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;mousemove&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;keydown&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pointerdown&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;eventName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;eventName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sendHit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;passive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If a reader has disabled JavaScript in their browser, I record the hit using a
CSS image. The &lt;code&gt;:hover&lt;/code&gt; pseudo-class loads it only after an interaction, another
trick &lt;a href=&quot;https://herman.bearblog.dev/how-bear-does-analytics-with-css/&quot; title=&quot;How Bear does analytics with CSS&quot;&gt;stolen from Bear Blog&lt;/a&gt;. Aboutâ€¯2% of my visitors fit into this
bucket.&lt;sup id=&quot;fnref:referrer&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:referrer&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-html codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;en&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nojs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// The JavaScript code for this blog requires ES6&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;noModule&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;HTMLScriptElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;documentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;nojs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;cm&quot;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;nojs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;hover&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;border-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;border-image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/count?p=/en/blog/2026-kpi-goodhart&amp;amp;t=Building...&amp;amp;r=NoJS&amp;amp;e=false&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where GoAccess reported around 2,000 visitors a day, GoatCounter counts fewer
than 200 humans.&lt;sup id=&quot;fnref:rss&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:rss&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; I assume AI scrapers use a low-effort approach: if the
content is available without barriers, as on this blog, they donâ€™t spawn a
complex mechanized browser that could trigger a page view. Even crawlers running
JavaScript, like &lt;a href=&quot;https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics&quot; title=&quot;Google Search Central: Understand the JavaScript SEO basics&quot;&gt;Googlebot with its headless Chromium&lt;/a&gt;, &lt;a href=&quot;https://developers.google.com/search/docs/crawling-indexing/javascript/lazy-loading#:~:text=Google%20Search%20does%20not%20interact%20with%20your%20page&quot; title=&quot;Google Search Central: Fix lazy-loaded content&quot;&gt;do not
interact with the page&lt;/a&gt; and never trigger the events I listen
to. The interaction-based â€œproof of humanityâ€� I use is likely to keep
working.&lt;sup id=&quot;fnref:css-test&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:css-test&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h1 id=&quot;local-proxy&quot;&gt;Local proxy&lt;/h1&gt;
&lt;p&gt;Five servers &lt;del&gt;across the world&lt;/del&gt; &lt;ins&gt;in Europe and in North
America&lt;/ins&gt; serve the content of this website, but GoatCounter runs on only
one of them. To avoid losing track of visitors when GoatCounter is down, I run a
local proxy listening on the same &lt;code&gt;/count&lt;/code&gt; endpoint. On each server, it stores
the hits in memory with a buffer large enough to survive several days of
downtime. It sends them in batches to the upstream backend using the
&lt;a href=&quot;https://www.goatcounter.com/help/api&quot; title=&quot;GoatCounter documentation: API&quot;&gt;&lt;code&gt;/api/v0/count&lt;/code&gt; authenticated endpoint&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&quot;lf-fullbleed&quot;&gt;&lt;div class=&quot;lf-media-outer&quot; style=&quot;width: 836px;&quot;&gt;&lt;span class=&quot;lf-media-inner&quot;&gt;&amp;amp;#128444; Servers on a map. web02 is in Paris, web03 in Helsinki, web04 in Nuremberg,
web05 in Ashburn, web06 in Chicago.&lt;/span&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;I proposed the code for the proxy in &lt;a href=&quot;https://github.com/arp242/goatcounter/pull/909&quot; title=&quot;PR #909: add a proxy to forward page counts&quot;&gt;pull request #909&lt;/a&gt;. GoatCounterâ€™s
maintainer declined to maintain so much code for such a niche use case. As a
fellow open-source developer, I often hold the same position for my own
projects: a one-time contributor effort may translate into a long-term
maintainer commitment.&lt;/p&gt;
&lt;p&gt;I expose the endpoint for the proxy on the domain of this website to evade ad
blockers. This sounds like I donâ€™t respect the readerâ€™s choice, but as
GoatCounter is privacy-friendly, I find it acceptable.&lt;/p&gt;
&lt;div class=&quot;language-nginx-configuration-file codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/count&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;access_log&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_pass&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://127.0.0.3:8087/count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_pass_request_headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Accept-Language&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$http_accept_language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;User-Agent&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$http_user_agent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;X-Real-Ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remote_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1 id=&quot;deploying-on-nixos&quot;&gt;Deploying on NixOS&lt;/h1&gt;
&lt;p&gt;My web servers run &lt;a href=&quot;https://nixos.org/&quot; title=&quot;Nix &amp;amp; NixOS: Declarative builds and deployments&quot;&gt;NixOS&lt;/a&gt;, a declarative Linux distribution with built-in
configuration management. I manage this small fleet with &lt;a href=&quot;https://colmena.cli.rs/&quot; title=&quot;Colmena documentation&quot;&gt;Colmena&lt;/a&gt;, a
stateless deployment tool for NixOS. My configuration is available on
&lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/&quot; title=&quot;vincentbernat/nixops-take1: Playground for NixOps&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;deploying-applications-in-containers&quot;&gt;Deploying applications in containers&lt;/h2&gt;
&lt;p&gt;For better isolation, each application runs inside an ephemeral lightweight
container, powered by &lt;a href=&quot;https://manpages.debian.org/systemd-nspawn.1.html&quot; title=&quot;Manual page for systemd-nspawn(1)&quot;&gt;systemd-nspawn&lt;/a&gt;. Each container runs a stripped-down
NixOS instance. A &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/modules/container.nix&quot; title=&quot;nixops-take1/modules/container.nix&quot;&gt;module wraps NixOSâ€™s &lt;code&gt;containers&lt;/code&gt; options&lt;/a&gt; to
avoid repeating the same options for each application.&lt;sup id=&quot;fnref:module&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:module&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; The containers
share their network namespace with the host: the additional isolation is not
worth the increased complexity. For a smaller footprint, I also disable a few
non-essential services.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# User-configurable settings for our custom module&lt;/span&gt;
  options&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;containers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkOption &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Ephemeral containers sharing the host network.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;attrsOf &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;submodule &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkOption &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;deferredModule&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;NixOS configuration of the container.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Translate our options to NixOS containers&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;containers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrs
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; container&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;ss&quot;&gt;ephemeral&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&quot;ss&quot;&gt;autoStart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;ss&quot;&gt;privateNetwork&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&quot;ss&quot;&gt;extraFlags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--resolv-conf=replace-host&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;          &lt;span class=&quot;ss&quot;&gt;imports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; container&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;config &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;          networking&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;firewall&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          system&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;stateVersion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;system&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;stateVersion&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          systemd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;services&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;            console-getty&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            systemd-logind&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            systemd-oomd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      cfg&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To configure a GoatCounter instance running in a container and listening on
&lt;code&gt;127.0.0.4:8088&lt;/code&gt;, we import the module&lt;sup id=&quot;fnref:import&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:import&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; and declare the container in the
&lt;code&gt;config.luffy.containers&lt;/code&gt; attribute set:&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; pkgs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;imports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;l&quot;&gt;./modules/container.nix&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;127.0.0.4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8088&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As the containers are ephemeral, we need to keep persistent data in directories
on the host. We add a &lt;code&gt;mounts&lt;/code&gt; option and ask NixOSâ€™s containers to expose the
configured directories through the &lt;code&gt;bindMounts&lt;/code&gt; option.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  options&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;containers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkOption &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;attrsOf &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;submodule &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;mounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkOption &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;listOf lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;str&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Host directories mounted read-write at the same place.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;containers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrs
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; container&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;bindMounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
          lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;genAttrs container&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mounts &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;hostPath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; path&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;isReadOnly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      cfg&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For example, to persist GoatCounterâ€™s database in the &lt;code&gt;/var/db/goatcounter&lt;/code&gt;
directory on the host, we add the directory to the &lt;code&gt;mounts&lt;/code&gt; option and alter the
service definition to tell GoatCounter where the database is.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;databaseDirectory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/db/goatcounter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;mounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; databaseDirectory &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;extraArgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-db=sqlite+&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;databaseDirectory&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/db.sqlite&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A container may also need some secrets. Colmena can &lt;a href=&quot;https://colmena.cli.rs/unstable/features/keys.html&quot; title=&quot;Colmena documentation: Secrets&quot;&gt;upload secrets&lt;/a&gt; without
storing them in the Nix store. We add a &lt;code&gt;keys&lt;/code&gt; option to our containers. It
takes an attribute set mapping secret names to the commands to populate them.
Then, the module declares the required secrets to Colmena in the
&lt;code&gt;deployment.keys&lt;/code&gt; option, makes the container depend on the presence of the
secrets, and exposes them to the container.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  options&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;containers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkOption &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;attrsOf &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;submodule &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkOption &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;attrsOf &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;listOf lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;types&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;str&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Secrets, as a command to run locally. They are mounted in /etc.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Colmena uploads each secret in `/var/keys` and make them available&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# to the group &quot;keys&quot;.&lt;/span&gt;
    deployment&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;concatMapAttrs
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; container&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrs
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; keyCommand&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;inherit&lt;/span&gt; keyCommand&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;permissions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0640&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;destDir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        container&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;keys&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      cfg&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# The container can only start if the required secrets are available.&lt;/span&gt;
    systemd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;services&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrs&#39;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; container&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;units&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;key&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-key.service&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;attrNames container&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;keys&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
        lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;nameValuePair &lt;span class=&quot;s2&quot;&gt;&quot;container@&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;requires&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; units&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; units&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      cfg&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Mount each secret inside the container.&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;containers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrs
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; container&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;bindMounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrs&#39;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; _&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;nameValuePair &lt;span class=&quot;s2&quot;&gt;&quot;/etc/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;key&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;ss&quot;&gt;hostPath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/keys/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;key&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;ss&quot;&gt;isReadOnly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
          container&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;keys&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      cfg&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For example, GoatCounter needs credentials to download the GeoIP database. I
provide a local command to fetch the secret from my password manager and expose
it inside the container through the &lt;code&gt;/etc/goatcounter.env&lt;/code&gt; environment file.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; pkgs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;keyCommand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; variable&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;pkgs&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;runtimeShell&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;-c&quot;&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;pass show personal/nixops/secrets | grep &#39;^&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;variable&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;=&#39;&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    keys&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;goatcounter.env&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; keyCommand &lt;span class=&quot;s2&quot;&gt;&quot;GOATCOUNTER_GEODB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      systemd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;goatcounter&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;serviceConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;EnvironmentFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/goatcounter.env&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;SupplementaryGroups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;keys&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;goatcounter-server&quot;&gt;GoatCounter server&lt;/h2&gt;
&lt;p&gt;Nixpkgs already packages GoatCounter. By overriding the &lt;code&gt;src&lt;/code&gt; and &lt;code&gt;vendorHash&lt;/code&gt;
attributes, I reuse its definition for my custom version with the proxy:&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; goatcounter&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; fetchFromGitHub &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
goatcounter&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;overrideAttrs &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;src&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; fetchFromGitHub &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;vincentbernat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;repo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;goatcounter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;rev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;feature/proxy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sha256-dJRlQlFu3tjcEgabT1LEbyFrasJlhmYu4L/T7EkoNcY=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;vendorHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sha256-c9Q5OrbZR+q6pD3SgPPWe8JUzcZco1AVUKGaV61k5DE=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I wrote a &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/modules/goatcounter.nix&quot; title=&quot;nixops-take1/modules/goatcounter.nix&quot;&gt;NixOS module&lt;/a&gt; to encapsulate GoatCounter: the
container definition, the service definition, and the secrets. The module
accepts the following options: &lt;code&gt;package&lt;/code&gt;, &lt;code&gt;serve.enable&lt;/code&gt;, &lt;code&gt;serve.listenAddress&lt;/code&gt;,
&lt;code&gt;serve.port&lt;/code&gt;, and &lt;code&gt;serve.databaseFile&lt;/code&gt;. I already detailed the container
configuration in the previous section. In the end, I chose not to reuse the
GoatCounter module from NixOS: itâ€™s small, so itâ€™s better to insulate my module
from unexpected future changes.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; pkgs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;goatcounter&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;databaseDirectory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;builtins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dirOf&lt;/span&gt; cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;serve&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databaseFile&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;chown&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;pkgs&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;coreutils&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/bin/chown -R&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;systemd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;GoatCounter Web Analytics&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;wantedBy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;multi-user.target&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;serviceConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;EnvironmentFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/goatcounter.env&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;SupplementaryGroups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;keys&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;DynamicUser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;Restart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;always&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;ExecStart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;escapeShellArgs &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;getExe cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;package&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;serve&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-listen=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;serve&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;listenAddress&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;toString&lt;/span&gt; cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;serve&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;port&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-tls=none&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-db=sqlite+&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;serve&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databaseFile&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-automigrate&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Transfer database ownership to dynamically assigned user &quot;goatcounter&quot;.&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;ExecStartPre&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;+&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;chown&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; goatcounter:goatcounter &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;databaseDirectory&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;ReadWritePaths&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; databaseDirectory&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following snippet configures GoatCounter to listen on &lt;code&gt;127.0.0.4:8088&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;serve&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;listenAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;127.0.0.4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8088&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The last step is to configure nginx to expose GoatCounter on the Internet. I
disable the &lt;code&gt;/count&lt;/code&gt; endpoint as the local proxy handles it.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;goatcounter&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;serve&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;nginx&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;virtualHosts&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;goatcounter.luffy.cx&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;forceSSL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;locations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;proxyPass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;listenAddress&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;toString&lt;/span&gt; cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;port&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;= /count&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;extraConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s s-Multiline&quot;&gt;&#39;&#39;&lt;/span&gt;
&lt;span class=&quot;s s-Multiline&quot;&gt;        return 404;&lt;/span&gt;
&lt;span class=&quot;s s-Multiline&quot;&gt;      &#39;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;goatcounter-proxy&quot;&gt;GoatCounter proxy&lt;/h2&gt;
&lt;p&gt;The same &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/modules/goatcounter.nix&quot; title=&quot;nixops-take1/modules/goatcounter.nix&quot;&gt;NixOS module&lt;/a&gt; configures the local proxy, with the
following options: &lt;code&gt;proxy.enable&lt;/code&gt;, &lt;code&gt;proxy.listenAddress&lt;/code&gt;, &lt;code&gt;proxy.port&lt;/code&gt;, and
&lt;code&gt;proxy.site&lt;/code&gt;â€”the site receiving the batches of page views. The local proxy has
no persistent data, but it needs the API key to authenticate to the main
GoatCounter instance: its container uses the &lt;code&gt;keys&lt;/code&gt; option but not the &lt;code&gt;mounts&lt;/code&gt;
option.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; pkgs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;goatcounter&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;keyCommand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; _&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;â€¦&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter-proxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    keys&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;goatcounter-proxy.env&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; keyCommand &lt;span class=&quot;s2&quot;&gt;&quot;GOATCOUNTER_API_KEY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;    config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;systemd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;GoatCounter Proxy.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;wantedBy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;multi-user.target&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;serviceConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;EnvironmentFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/goatcounter-proxy.env&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;SupplementaryGroups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;keys&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;DynamicUser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;Restart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;always&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;ExecStart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;escapeShellArgs &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;getExe cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;package&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;proxy&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-site=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;proxy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;site&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-listen=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;proxy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;listenAddress&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;toString&lt;/span&gt; cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;proxy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;port&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;-ratelimit=10/1&quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 10 requests per second per IP&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For each server, I enable the local proxy with the following snippet. The
nginx configuration shown earlier exposes the &lt;code&gt;/count&lt;/code&gt; endpoint under the same
domain as my blog.&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;site&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;goatcounter.luffy.cx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;listenAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;127.0.0.3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8087&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;backup-of-the-sqlite-database-with-litestream&quot;&gt;Backup of the SQLite database with Litestream&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://litestream.io/&quot; title=&quot;Litestream: Streaming SQLite Replication&quot;&gt;Litestream&lt;/a&gt; is a streaming replication tool for SQLite databases. It
compresses the changes committed to the write-ahead log (&lt;abbr title=&quot;Write-ahead log&quot;&gt;WAL&lt;/abbr&gt;) next to the
database and sends them to a remote destination. I encapsulate its configuration
in a &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/modules/litestream.nix&quot; title=&quot;nixops-take1/modules/litestream.nix&quot;&gt;NixOS module&lt;/a&gt;, which takes an attribute set &lt;code&gt;databases&lt;/code&gt;
mapping a name to the path of the database to back up.&lt;/p&gt;
&lt;p&gt;Litestream also runs in a container. I mount the databases to replicate, as well
as the secrets to push the backups to a &lt;a href=&quot;https://www.hetzner.com/storage/storage-box/&quot; title=&quot;Hetzner Storage Box&quot;&gt;Hetzner storage box&lt;/a&gt; using &lt;abbr title=&quot;Secure File Transfer Protocol&quot;&gt;SFTP&lt;/abbr&gt;:&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; pkgs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;litestream&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;databaseDirs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;unique &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;builtins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dirOf&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;builtins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;attrValues cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databases&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkIf &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databases &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;litestream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;mounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; databaseDirs&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      keys&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;litestream.env&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;pkgs&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;runtimeShell&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;-c&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;pass show personal/nixops/secrets | grep &#39;^SQLITE_BACKUP_&#39;&quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Inside the container, I configure Litestream through NixOSâ€™s
&lt;code&gt;services.litestream&lt;/code&gt; options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;full snapshots every day, kept for 15 days,&lt;/li&gt;
&lt;li&gt;three &lt;a href=&quot;https://fly.io/blog/litestream-v050-is-here/&quot; title=&quot;Litestream v0.5.0 is Here&quot;&gt;levels of compaction&lt;/a&gt; for transaction files: 5 minutes, 30 minutes, and 3 hours,&lt;/li&gt;
&lt;li&gt;auto-recovery,&lt;sup id=&quot;fnref:auto-recover&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:auto-recover&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;replica stored in a directory matching the host name, and&lt;/li&gt;
&lt;li&gt;credentials read from &lt;code&gt;/etc/litestream.env&lt;/code&gt; and exposed through variable expansion.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; pkgs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; lib&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;litestream&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;containers&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;litestream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# The databases belong to dynamically allocated users, whose UID is&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# not known here, so Litestream runs as root.&lt;/span&gt;
      systemd&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;litestream&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;serviceConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkForce &lt;span class=&quot;s2&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mkForce &lt;span class=&quot;s2&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Use NixOS service.&lt;/span&gt;
      services&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;litestream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;environmentFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/litestream.env&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;auto-recover&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;snapshot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;ss&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;24h&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;ss&quot;&gt;retention&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;360h&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;levels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;5m&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;30m&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;3h&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;dbs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; lib&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;mapAttrsToList
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;inherit&lt;/span&gt; path&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;ss&quot;&gt;replica&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sftp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{SQLITE_BACKUP_HOST}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{SQLITE_BACKUP_USER}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{SQLITE_BACKUP_PASSWORD}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;host-key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{SQLITE_BACKUP_HOSTKEY}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;networking&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;hostName&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
            cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databases&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To back up GoatCounterâ€™s database, I declare a &lt;code&gt;goatcounter&lt;/code&gt; attribute in
&lt;code&gt;luffy.litestream.databases&lt;/code&gt;, set to the database path:&lt;/p&gt;
&lt;div class=&quot;language-nix codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; config&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; config&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;goatcounter&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;serve&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  luffy&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;litestream&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databases&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;goatcounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; cfg&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;databaseFile&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the &lt;abbr title=&quot;Secure File Transfer Protocol&quot;&gt;SFTP&lt;/abbr&gt; server, we can inspect Litestreamâ€™s work, with the compacted
transactions and the full snapshots:&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;â�¯ &lt;/span&gt;ls&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;web02/goatcounter/ltx
&lt;span class=&quot;go&quot;&gt;web02/goatcounter/ltx/0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;web02/goatcounter/ltx/1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;web02/goatcounter/ltx/2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;web02/goatcounter/ltx/3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;web02/goatcounter/ltx/9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;â�¯ &lt;/span&gt;ls&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-lh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;web02/goatcounter/ltx/1
&lt;span class=&quot;go&quot;&gt;29.1K Sep  5 01:25 0000000000003f2a-0000000000003f2b.ltx&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;72.4K Sep  5 02:03 0000000000003f2c-0000000000003f2d.ltx&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;63.3K Sep  5 02:24 0000000000003f2e-0000000000003f2f.ltx&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[â€¦]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;â�¯ &lt;/span&gt;ls&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-lh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;web02/goatcounter/ltx/9
&lt;span class=&quot;go&quot;&gt; 8.5M Sep  5 02:00 0000000000000001-0000000000003f2b.ltx&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; 8.5M Sep  6 02:03 0000000000000001-0000000000004008.ltx&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; 8.6M Sep  7 02:03 0000000000000001-00000000000043a8.ltx&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[â€¦]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can restore the database from the backup with a few shell commands. First, we
stop the containers. Then, we move the damaged database away, invoke &lt;code&gt;litestream
restore&lt;/code&gt; from the right environment, and restart the containers.&lt;sup id=&quot;fnref:slow&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:slow&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash-session codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;# &lt;/span&gt;systemctl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;stop&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;container@goatcounter&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;container@litestream
&lt;span class=&quot;gp&quot;&gt;# &lt;/span&gt;mv&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/var/db/goatcounter/db.sqlite&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;,.old&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/etc/nixos-containers/litestream.conf&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-a&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/var/keys/litestream.env&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;+a&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SYSTEM_PATH&lt;/span&gt;/sw/bin/litestream&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;restore&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-config&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SYSTEM_PATH&lt;/span&gt;/etc/litestream.yml&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/var/db/goatcounter/db.sqlite&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;# &lt;/span&gt;ls&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-lh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/var/db/goatcounter/db.sqlite
&lt;span class=&quot;go&quot;&gt;-rw-r--r-- 1 root root 20M Sep 20 07:33 /var/db/goatcounter/db.sqlite&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;# &lt;/span&gt;systemctl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;start&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;container@goatcounter&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;container@litestream
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr /&gt;
&lt;p&gt;Ten years after &lt;a href=&quot;https://vincent.bernat.ch/en/blog/2018-more-privacy-blog&quot; title=&quot;A more privacy-friendly blog&quot;&gt;removing Google Analytics&lt;/a&gt;, JavaScript-based analytics is
back on this blog, but without storing cookies or IP addresses, and without
involving a third party. I still write for myself first, notably because it lets
me dig into a topic and refer back to it years later. But knowing a bit more
about my fellow human readers is a nice bonus, even the ones disabling
JavaScript. ğŸ��&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn:scrub&quot;&gt;
&lt;p&gt;Nginx scrambles IP addresses before storing them, thanks to the &lt;a href=&quot;https://github.com/masonicboom/ipscrub&quot; title=&quot;ipscrub: IP address anonymizer module for nginx&quot;&gt;&lt;code&gt;ipscrub&lt;/code&gt;
nginx module&lt;/a&gt;.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:scrub&quot; title=&quot;Jump back to footnote 1 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:bot-filter&quot;&gt;
&lt;p&gt;GoatCounter already filters some bots based on the user agent or the IP
address. But AI scrapers lie about their user agent and hide behind
&lt;a href=&quot;https://jacob.gold/posts/residential-proxies-are-a-national-security-threat/&quot; title=&quot;Residential Proxies Are a National Security Threat&quot;&gt;residential proxies&lt;/a&gt;.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:bot-filter&quot; title=&quot;Jump back to footnote 2 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:referrer&quot;&gt;
&lt;p&gt;Without JavaScript, I cannot send the real referrer. I insert â€œNoJSâ€�
instead.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:referrer&quot; title=&quot;Jump back to footnote 3 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:rss&quot;&gt;
&lt;p&gt;I am missing the humans reading the RSS feed. I am not comfortable adding a
&lt;a href=&quot;https://www.goatcounter.com/help/pixel&quot; title=&quot;GoatCounter documentation: tracking pixel without JavaScript&quot;&gt;tracking pixel&lt;/a&gt;, and bots are likely to fetch it, compromising the
statistics. Iâ€™ll live without counting these readers.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:rss&quot; title=&quot;Jump back to footnote 4 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:css-test&quot;&gt;
&lt;p&gt;In Februaryâ€¯2025, I tested another CSS-only approach without the interaction
trick: each page loaded an empty image as a background. Over a month, it
recorded up to ten times fewer page views than the nginx logs, even after
removing user agents identifying as bots. Compared to this experiment,
GoatCounter counts about three times fewer views, 18 months later. As the
time ranges differ, this is not an apples-to-apples comparison, but it gives
a hint about how efficient bot filtering is.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:css-test&quot; title=&quot;Jump back to footnote 5 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:module&quot;&gt;
&lt;p&gt;A &lt;a href=&quot;https://nixos.org/manual/nixos/stable/#sec-writing-modules&quot; title=&quot;NixOS Manual: Writing NixOS Modules&quot;&gt;NixOS module&lt;/a&gt; is a function receiving the configuration of the whole
system as &lt;code&gt;config&lt;/code&gt; and returning three attributes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;imports&lt;/code&gt; adds other modules to import,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;options&lt;/code&gt; declares user-configurable settings, each with a type and a default value, and&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config&lt;/code&gt; sets values for options declared by any module, like &lt;code&gt;containers&lt;/code&gt; from NixOS.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a module does not need to declare options, you can return the &lt;code&gt;config&lt;/code&gt; attribute
set directly. When a module does not require any argument, you can define it as an attribute
set instead.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:module&quot; title=&quot;Jump back to footnote 6 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:import&quot;&gt;
&lt;p&gt;Most of the time, you donâ€™t need an explicit import. NixOS &lt;a href=&quot;https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/module-list.nix&quot; title=&quot;nixpkgs/nixos/modules/module-list.nix&quot;&gt;automatically
imports&lt;/a&gt; the modules shipped with Nixpkgs. For my own
modules, &lt;a href=&quot;https://github.com/vincentbernat/nixops-take1/blob/master/modules/default.nix&quot; title=&quot;nixops-take1/modules/default.nix&quot;&gt;some machinery&lt;/a&gt; also imports them automatically.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:import&quot; title=&quot;Jump back to footnote 7 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:auto-recover&quot;&gt;
&lt;p&gt;Litestream &lt;a href=&quot;https://litestream.io/reference/config/#auto-recover&quot; title=&quot;Litestream: auto-recover option&quot;&gt;warns against using the &lt;code&gt;auto-recover&lt;/code&gt; option&lt;/a&gt; as
it can cause data loss. But I donâ€™t properly monitor my servers and I prefer
uninterrupted backups to a slight chance of losing the last few records.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:auto-recover&quot; title=&quot;Jump back to footnote 8 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:slow&quot;&gt;
&lt;p&gt;In my case, the process is slow: around 20 minutes for a 20â€¯MiB database.
You can test by restoring to a copy with the &lt;code&gt;-o&lt;/code&gt; option, but you still need
to stop the Litestream container.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:slow&quot; title=&quot;Jump back to footnote 9 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Sun, 20 Sep 2026 19:44:50 +0000</pubDate>

</item> 
<item>
	<title>Andrew Cater: Debian 11 is at end of life from Long Term Support</title>
	<guid>tag:blogger.com,1999:blog-8085113335874848981.post-6303472353413203122</guid>
	<link>http://flosslinuxblog.blogspot.com/2026/09/debian-11-is-at-end-of-life-from-long.html</link>
     <description>  &lt;p&gt; Lots of posts in the debian-user mailing list complaining about updates with Debian 11.11 suddenly failing.&lt;br /&gt;&lt;br /&gt;See&lt;a href=&quot;https://www.debian.org/News/2026/20260831?=0&quot;&gt; Debian 11 Long Term Support reaches end-of-life&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;August 31st, 2026&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
The Debian Long Term Support (LTS) Team hereby announces that Debian 11
&lt;q&gt;bullseye&lt;/q&gt; support has reached its end-of-life today, 31 August 2026,
five years after its initial release on 14 August 2021.
&lt;/p&gt;
&lt;p&gt;
Starting in September, Debian will not provide further security updates for
Debian 11. A subset of &lt;q&gt;bullseye&lt;/q&gt; packages will be supported by external
parties. Detailed information can be found at
&lt;a href=&quot;https://wiki.debian.org/LTS/Extended&quot;&gt; Extended LTS&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The Debian LTS Team is currently providing security support for Debian 12
&lt;q&gt;bookworm&lt;/q&gt;, the current oldstable release. Thanks to the combined efforts
of different teams including the Security Team, the Release Team, and the LTS
Team, the Debian 12 life cycle encompasses five years.
Debian 12 will receive Long Term Support until 30 June 2028. The supported
architectures in Debian 12 LTS are amd64, i386, arm64, armhf and ppc64el.
&lt;/p&gt;
&lt;p&gt;
For further information about using &lt;q&gt;bookworm&lt;/q&gt; LTS and upgrading from
&lt;q&gt;bullseye&lt;/q&gt; LTS, please refer to
&lt;a href=&quot;https://wiki.debian.org/LTS/Using&quot;&gt;LTS/Using&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Debian and its LTS Team would like to thank all contributing users, developers,
sponsors and other Debian teams who are making it possible to extend the life
of previous stable releases, and who have made Bullseye LTS a success.
&lt;/p&gt;
&lt;p&gt;
If you rely on Debian LTS, please consider
&lt;a href=&quot;https://wiki.debian.org/LTS/Development&quot;&gt;joining the team&lt;/a&gt;,
providing patches, testing or
&lt;a href=&quot;https://wiki.debian.org/LTS/Funding&quot;&gt;funding the efforts&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt; &lt;/p&gt; </description> 
	<pubDate>Sun, 20 Sep 2026 15:04:40 +0000</pubDate>
  <author>noreply@blogger.com (Andrew Cater)</author>  
</item> 
<item>
	<title>Paul Tagliamonte: Why Write?</title>
	<guid>https://notes.pault.ag/why-write/</guid>
	<link>https://notes.pault.ag/why-write/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/paultag.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;As a graduate of a liberal arts university, I wound up, unsurprisingly, taking a
lot of classes in every possible academic discipline. Thinking back to the
person that I was going into university, I don’t think I would have chosen to
take them – after all, my degree was in the sciences; I’d have been stoked to
do nothing more than wall-to-wall computer science until I ran out of
coursework and filled the rest of my hours with research and independent
studies with my professors (which, I guess I did actually do, just not as
much as I would have otherwise).&lt;/p&gt;
&lt;p&gt;Even this blog’s CSS theme (now 18 years old and starting to look it) was
something I wrote after receiving and repeatedly re-reading a tattered
third-hand copy of “The Laws of Thought” by George Boole. It was gifted to me
by a college friend majoring in philosophy while I was crashing at his rental
on the beach. He gave it to me because he knew I “liked that shit” and, while
it was definitely computer science in nature, I would not have read it
otherwise. I have vivid memories of sleeping on his la-z-boy surrounded by
towers of books he was working through. He went on to do incredible work,
getting his PhD, doing research, brilliant writing – his death in 2023 has
robbed humanity of more time with him. “The Laws of Thought” sits behind me in
my office, and is one of my most valued possessions.&lt;/p&gt;
&lt;p&gt;My friends mean more to me than I could ever express, and I definitely don’t
show it enough. Each of my classes made me a more thoughtful person. My
professors made me a better, more well-rounded person – and a person who
attempts to live up to the oft repeated credo of being “men and women for
others”. I did the best I could, even though I was never a particularly good
student. Without liberal arts, I don’t think I would, dispositionally, have
been capable of pushing myself – to this day – to continue to learn on nights
and weekends, for no reason other than wanting to learn. I &lt;em&gt;refuse&lt;/em&gt; to stop
expanding my perspective, and do my best to approach new problems with as much
humility and curiosity as I can muster.&lt;/p&gt;
&lt;p&gt;Every few days for the last year or so, I have been thinking back to a reading
assignment from my junior year that, at the time, I thought was a borderline
throwaway filler assignment for the class. The reading is an essay from 1947 by
the french existentialist philosopher and libertarian marxist, Jean-Paul Sartre
(as some of the more erudite may have now already worked out given the blog’s
title), “Why Write?”. I re-read it this week. It is not filler. I remember this
essay better than some of the classwork I considered more important at the
time.&lt;/p&gt;
&lt;h1 id=&quot;why-write&quot;&gt;Why Write?&lt;/h1&gt;
&lt;p&gt;“Why Write?” starts off by describing the ways in which writing – trying to
communicate your thoughts, opinions, or feelings to others – is an act of
&lt;em&gt;projection&lt;/em&gt;. The writer will only ever draw from a place of their “own
subjectivity” – writing is taking your person and putting it on display.
You’re choosing what words to use, how to use them, pulling from knowledge
you’ve accumulated (based on how you’ve chosen to spend your time). Spending
any amount of your finite existence in order to convey a thought is, itself,
announcing to the world that you believe it to be a thought worth sharing.&lt;/p&gt;
&lt;p&gt;Meanwhile, the act of reading is &lt;em&gt;not simply&lt;/em&gt; turning letters into words.
Reading is engaging with the work, and &lt;em&gt;understanding&lt;/em&gt; the work in a process
that looks more like what Sartre terms “re-invention” or “discovery” – “the
literary object, though realized &lt;em&gt;through&lt;/em&gt; language, is never given &lt;em&gt;in&lt;/em&gt;
language”. It is not enough to read the words in a book end-to-end; you must,
as a reader, actively engage with the work to understand what is being
communicated by those words. Reading is to take the words on the page, and
“exceed” the mere words through what he calls “directed creation”. The reader
is “re-inventing”/“discovering” the writer’s thoughts by following their
“landmarks in the void”.&lt;/p&gt;
&lt;p&gt;And this all makes pretty good sense to me – I know if someone is being
sarcastic because I know the writer; I have read their words and have &lt;em&gt;read&lt;/em&gt;
into their words, allowing myself to be directed by the writer into
“discovering” the thought they have left me in their work. I understand that
their words are &lt;em&gt;humorous&lt;/em&gt;, not &lt;em&gt;irate&lt;/em&gt;. Knowing who the author of a work is
can completely change the point of a sentence. The fact I’m writing about
Sartre at all, or that this very writing has been constrained for presentation
in this blog’s CSS is only happening because of who I am, what things I’ve
experienced in life, and what has made me, me. Sartre argues that this dyadic
coupling between writer and writing means that I, as a writer, can never truly
&lt;em&gt;read&lt;/em&gt; my own writing. I will never be capable of &lt;em&gt;reading&lt;/em&gt; my own work and
getting something out of it – the work is already an extension of my own
person. I can discover no thought in my own works.&lt;/p&gt;
&lt;p&gt;Of course, Sartre, as an existentialist, is honor bound to go one step further
here – the reader, by participating in &lt;em&gt;reading&lt;/em&gt; a work, is asserting their
own freedom. Every time a writer writes “[…] the writer appeals to the
reader’s freedom to collaborate in the production of [their] work”. The
creative act may only be complete if both writer and reader have recognized one
another and made a choice to do so. No one is &lt;em&gt;compelled&lt;/em&gt; to complete the
creative act. The things you &lt;em&gt;read&lt;/em&gt; matter. Reading something fundamentally
alters you as a person – you can not simply un-read a thought. Everything you
read changes your universe. I have a hunch Sartre would find things like the
(original early 2010s era) “tl;dr” reply to obviously terrible writing
absolutely hilarious as a reader’s expression of freedom (not to be confused
with modern 2020s era usage as shorthand for “summary section”). Using your
freedom to choose to complete the writer’s creative act (or not) is inherently
asserting your humanity.&lt;/p&gt;
&lt;p&gt;I’m a bit fuzzy on the specifics of this quote, but I think it was
&lt;a href=&quot;https://meta.wikimedia.org/wiki/User:Sj&quot;&gt;sj&lt;/a&gt; who told me at one year’s
&lt;a href=&quot;https://puzzles.mit.edu/&quot;&gt;Mystery Hunt&lt;/a&gt; that “A puzzle is a contract between
puzzle author and puzzle solver, the author promises that the puzzle is
solvable if you’re clever enough”. The puzzle author and puzzle solver are
engaging in a collaborative production of the work that is only possible by
recognizing one another. Similarly, Sartre – “whatever connections [the
reader] may establish among the different parts of the book among the chapters
or the words [the reader] has a guarantee, namely, that they have been
expressly willed”.&lt;/p&gt;
&lt;h1 id=&quot;wall-drawing-123&quot;&gt;Wall Drawing #123&lt;/h1&gt;
&lt;p&gt;It follows, Sartre argues, that the act of writing, as a means to convey a
thought to a reader, may only be completed through the act of &lt;em&gt;reading&lt;/em&gt;.
&lt;em&gt;Reading&lt;/em&gt; can only be done by others; writing, therefore, only exists to be
&lt;em&gt;read&lt;/em&gt; – it can serve no other purpose. Writing and reading are two halves of
the same creative, collaborative act, only satisfied when both writer and
reader acknowledge one another. Combined, writing and reading are the act of
recognizing one another’s humanity, thoughts, experiences, consciousness – the
act of co-creation of thought is the critical aspect of writing and reading –
reconstructing the author’s perspective, thought, intent, point. The
co-creation &lt;em&gt;is the point&lt;/em&gt; of both &lt;em&gt;reading&lt;/em&gt; and &lt;em&gt;writing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Writing without anyone to &lt;em&gt;read&lt;/em&gt; the work leaves the writer’s bid for
co-creation unsatisfied and humanity unrecognized. No thought has been conveyed
to any reader, no one has understood the reason behind the “landmarks in the
void” you’ve carefully placed, leaving you to either “[…] put down [your] pen
or despair”. Writing is an appeal to the reader’s freedom, and the nature of
that freedom is the writer can not control it – never being understood is
always a possibility any time anyone sets out to write.&lt;/p&gt;
&lt;p&gt;Nearly 12 years ago, I attempted to read the text on the &lt;a href=&quot;https://git-man-page-generator.lokaltog.net/&quot;&gt;git manpage
generator&lt;/a&gt; for the first time –
I remember the &lt;strong&gt;exact&lt;/strong&gt; feeling of my brain going into “git manpage parsing
mode” where every word was dragging git plumbing megaliths through the sand
from their far-flung homes. I can still feel the surface of my desk as I
instinctually started to trace out logical connections between git internals
referenced as I read along. It took me a good 20 seconds to realize what I was
reading made no sense. This website broke Sartre’s writer-reader agreement – I
was attempting to &lt;em&gt;read&lt;/em&gt; this website, but there was nothing there. You can
“mechanically” “read” the &lt;code&gt;git-man-page-generator&lt;/code&gt;, but you can never &lt;em&gt;read&lt;/em&gt; it
– it is not possible to &lt;em&gt;read&lt;/em&gt; it. It was funny – unsettling. Each grasp at a
real-looking image in front of me misses, my hand coming back empty. I
couldn’t get enough of it. I must have tried to read a dozen generations in a
row. I had never had something quite that broken pass that far into my
consciousness before. Although I kept trying, it never did feel quite the same
as that first time; I think fundamentally, I couldn’t forget that it was
random.&lt;/p&gt;
&lt;p&gt;While never having anyone &lt;em&gt;read&lt;/em&gt; your &lt;em&gt;writing&lt;/em&gt; drives them to “put down your
pen or despair”, Sartre never had to contend with the opposite problem – being
asked to &lt;em&gt;read&lt;/em&gt; that which was not &lt;em&gt;written&lt;/em&gt;. &lt;em&gt;Reading&lt;/em&gt; that which was not
&lt;em&gt;written&lt;/em&gt; does not merely leave someone unrecognized when a reader makes a
choice; instead, it is an &lt;strong&gt;inherent violation of the contract between reader
and writer&lt;/strong&gt;. Not only is no humanity being recognized through attempting to
&lt;em&gt;read&lt;/em&gt; words which were not &lt;em&gt;written&lt;/em&gt;, but the &lt;u&gt;reader&lt;/u&gt;, not the writer,
is the one who bears the burden of unexpected apophenia. The &lt;u&gt;reader&lt;/u&gt;,
while engaging in co-creation, must now contort themselves to uphold their end
of the Sartrean agreement, scrutinizing text to ascribe consciousness,
thought and intent only to come back up with pareidolia-fueled echos of
one’s own self and disfigured half-thoughts of others. The reality is, the
modern reader must now “mechanically” “read” most written work they come
across, scrutinizing text for any signs of thought before truly attempting
to &lt;em&gt;read&lt;/em&gt; the work. Failing to do this correctly changes our person –
each time it happens, a small part of us is irrevocably altered. Choosing to
engage in this ballet because you wish to do so is one thing – this is
your right and freedom as a reader – but passing words which were not
&lt;em&gt;written&lt;/em&gt; as your own in an attempt to wrestle a reader’s freedom of
co-creation from them is another entirely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you didn’t write it, I don’t want to read it (dw;dr). Send me your prompt instead.&lt;/strong&gt;&lt;/p&gt; </description> 
	<pubDate>Fri, 18 Sep 2026 17:05:00 +0000</pubDate>

</item> 
<item>
	<title>Louis-Philippe Véronneau: Fake Cash: The World Trade Game</title>
	<guid>tag:veronneau.org,2026-09-18:/fake-cash-the-world-trade-game.html</guid>
	<link>https://veronneau.org/fake-cash-the-world-trade-game.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/pollo.png&quot; width=&quot;65&quot; height=&quot;70&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;This is a new series&lt;sup id=&quot;fnref:series&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://veronneau.org/feeds/languages/en.atom.xml#fn:series&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; I&#39;m starting on the tools I have been crafting and
buying to play pedagogical games in my Economics classes.&lt;/p&gt;
&lt;p&gt;These games, aside from being just plain fun for the students, often aim to
teach them a lesson via interactive play. Unsurprisingly, it is much easier for
them to &lt;a href=&quot;https://en.wiktionary.org/wiki/grok&quot;&gt;grok&lt;/a&gt; a particular concept this way. Moreover, many students told me
these activities were the best part of the classes I teach.&lt;/p&gt;
&lt;h1&gt;The World Trade Game&lt;/h1&gt;
&lt;p&gt;I found out about The World Trade Game in &lt;em&gt;The Handbook of Pluralist Economics
Education&lt;/em&gt;&lt;sup id=&quot;fnref:handbook&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://veronneau.org/feeds/languages/en.atom.xml#fn:handbook&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, which also contains many other fun pedagogical games. It
was first developed by &lt;a href=&quot;https://actionaid.org/&quot;&gt;Action Aid&lt;/a&gt;, but has since been refined by &lt;a href=&quot;https://economicsnetwork.ac.uk/showcase/sloman_game&quot;&gt;John
Sloman&lt;/a&gt; and then by Irene van Staveren, who wrote about her use of the game in
the aforementioned book.&lt;/p&gt;
&lt;p&gt;The goal of this blog entry is not to describe the game and teach you how to
play it. If that interests you, either buy the book I mentioned or read about
Sloman&#39;s version &lt;a href=&quot;https://economicsnetwork.ac.uk/showcase/sloman_game&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;No, our focus point here is the &lt;em&gt;tools&lt;/em&gt; to play this game: fake cash! Fake cash
can be used in many economics pedagogical games and in my opinion, is a
worthwhile &quot;investment&quot; of your time and energy. You could indeed play with
regular printed sheets of paper listing a value (I sure did!), but using Play
Money (a more appropriate term, since we&#39;re not trying to defraud anyone) will
up your game and create a more immersive atmosphere in your classes.&lt;/p&gt;
&lt;p&gt;At first, I tried to buy play money. Surely, some commercial offering aiming to
create realistic props for movies and TV productions existed? At least in
Canada, it turns out the answer was no. The only thing I could find were shady
websites and weird expensive listings on AliExpress. Not being tenured yet, I
did not try to convince my employer to take a 50-50 chance on supporting
criminal endeavours.&lt;/p&gt;
&lt;p&gt;As such, the next best thing I found was &lt;a href=&quot;https://www.bankofcanadamuseum.ca/2020/11/printable-play-money/&quot;&gt;printable play money designed by the
Bank of Canada Museum&lt;/a&gt;. Their designs were quite nice and met my needs,
but their PDF layout made it overly complicated to print large quantities of
bills. As such, I played around with GIMP a little and came out with these
files. A commercial printer shouldn&#39;t have issues printing them on glossy
cardstock paper and cutting them up for you:&lt;/p&gt;
&lt;div class=&quot;grid-container&quot;&gt;
    &lt;div class=&quot;grid-item&quot;&gt;
      &lt;a href=&quot;https://veronneau.org/media/blog/2026-09-18/5.pdf&quot;&gt;
        &lt;img alt=&quot;Three Canadian 5$ bills&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/5.jpg&quot; style=&quot;width: 100%;&quot; title=&quot;Three Canadian 5$ bills&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;
    &lt;div class=&quot;grid-item&quot;&gt;
      &lt;a href=&quot;https://veronneau.org/media/blog/2026-09-18/10.pdf&quot;&gt;
        &lt;img alt=&quot;Three Canadian 10$ bills&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/10.jpg&quot; style=&quot;width: 100%;&quot; title=&quot;Three Canadian 10$ bills&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;
    &lt;div class=&quot;grid-item&quot;&gt;
      &lt;a href=&quot;https://veronneau.org/media/blog/2026-09-18/20.pdf&quot;&gt;
        &lt;img alt=&quot;Three Canadian 20$ bills&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/20.jpg&quot; style=&quot;width: 100%;&quot; title=&quot;Three Canadian 20$ bills&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;
    &lt;div class=&quot;grid-item&quot;&gt;
      &lt;a href=&quot;https://veronneau.org/media/blog/2026-09-18/50.pdf&quot;&gt;
        &lt;img alt=&quot;Three Canadian 50$ bills&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/50.jpg&quot; style=&quot;width: 100%;&quot; title=&quot;Three Canadian 50$ bills&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;
    &lt;div class=&quot;grid-item&quot;&gt;
      &lt;a href=&quot;https://veronneau.org/media/blog/2026-09-18/100.pdf&quot;&gt;
        &lt;img alt=&quot;Three Canadian 100$ bills&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/100.jpg&quot; style=&quot;width: 100%;&quot; title=&quot;Three Canadian 100$ bills&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Once printed and cut, you&#39;ll unfortunately have to fold each bill by hand. To
secure both halves, I ended up using a strip of transparent tape on each long
edge.&lt;/p&gt;
&lt;p&gt;Here is the result, with a real Canadian 20$ bill as a comparison:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Stacks of play money bills, with examples of the 5$, 10$, 20$, 50$ and 100$ bills&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/stacks.jpg&quot; style=&quot;margin-left: 15%;&quot; title=&quot;Stacks of play money bills, with examples of the 5$, 10$, 20$, 50$ and 100$ bills&quot; width=&quot;70%&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A real Canadian 20$ bill, side-to-side with the play money version&quot; src=&quot;https://veronneau.org/media/blog/2026-09-18/comparison.jpg&quot; style=&quot;margin-left: 15%;&quot; title=&quot;A real Canadian 20$ bill, side-to-side with the play money version&quot; width=&quot;70%&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn:series&quot;&gt;
&lt;p&gt;Don&#39;t hold your breath though, as I do not currently have a release
schedule. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://veronneau.org/feeds/languages/en.atom.xml#fnref:series&quot; title=&quot;Jump back to footnote 1 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:handbook&quot;&gt;
&lt;p&gt;Reardon, J. (2009). The Handbook of Pluralist Economic Education. New York : Routledge. &lt;a class=&quot;footnote-backref&quot; href=&quot;https://veronneau.org/feeds/languages/en.atom.xml#fnref:handbook&quot; title=&quot;Jump back to footnote 2 in the text&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Fri, 18 Sep 2026 04:00:00 +0000</pubDate>

</item> 
<item>
	<title>Russell Coker: Nheko DBUS</title>
	<guid>https://etbe.coker.com.au/?p=6292</guid>
	<link>https://etbe.coker.com.au/2026/09/17/nheko-dbus/</link>
     <description>  &lt;p&gt;Nheko is my current favourite client for the Matrix IM system, which is my favourite IM system.&lt;/p&gt;
&lt;p&gt;Matrix is an open system with end to end encryption and Nheko is free software and runs well on Linux desktops and phones.&lt;/p&gt;
&lt;p&gt;The Nheko client allows interaction with dbus which could be good for automating things, EG you could change the status message when unlocking the screen. I’m documenting the most useful ones here because they don’t seem to be documented anywhere else. I have filed a Debian bug about the activate room option not working. The &lt;b&gt;qdbus6&lt;/b&gt; program is the QT6 version of the dbus command-line query program, there are a range of other programs which work in much the same way.&lt;/p&gt;
&lt;pre&gt;# list all interfaces
qdbus6 im.nheko.Nheko / 
# get the version of Nheko
qdbus6 im.nheko.Nheko / im.nheko.Nheko.nhekoVersion
# list rooms in a dump of the data structures (pity it&#39;s not json or something)
qdbus6 --literal im.nheko.Nheko / im.nheko.Nheko.rooms|less
# join a room
qdbus6 im.nheko.Nheko / im.nheko.Nheko.joinRoom &quot;#flounder-random:luv.asn.au&quot;
# supposed to activate a room but doesn&#39;t
qdbus6 im.nheko.Nheko / im.nheko.Nheko.activateRoom &quot;#flounder-random:luv.asn.au&quot;
# set the status
qdbus6 im.nheko.Nheko / im.nheko.Nheko.setStatusMessage &quot;whatever&quot;
# get the status
qdbus6 im.nheko.Nheko / im.nheko.Nheko.statusMessage&lt;/pre&gt;
&lt;p&gt;Here are a couple of examples of using other dbus clients to get similar results. Note that the difference between the Debian version of Nheko (and maybe other recent versions) and what LLMs return for usage examples is that Debian has “/” as the path while the examples have “/im/nheko/Nheko”.&lt;/p&gt;
&lt;pre&gt;# list rooms via gdbus
gdbus call --session --dest im.nheko.Nheko --object-path / --method im.nheko.Nheko.rooms
# get status via dbus-send
dbus-send --session --print-reply --type=method_call --dest=im.nheko.Nheko / im.nheko.Nheko.statusMessage&lt;/pre&gt;
&lt;div class=&quot;yarpp yarpp-related yarpp-related-rss yarpp-template-list&quot;&gt;

&lt;p&gt;Related posts:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2007/01/15/dbus-error/&quot; rel=&quot;bookmark&quot; title=&quot;dbus error&quot;&gt;dbus error&lt;/a&gt; &lt;small&gt;Strange dbus error from the KDE power monitoring tool...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2022/03/28/hangouts-replacement/&quot; rel=&quot;bookmark&quot; title=&quot;Hangouts Replacement&quot;&gt;Hangouts Replacement&lt;/a&gt; &lt;small&gt;Google is currently in the process of killing Hangouts. Last...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2023/07/09/matrix/&quot; rel=&quot;bookmark&quot; title=&quot;Matrix&quot;&gt;Matrix&lt;/a&gt; &lt;small&gt;Introduction In 2020 I first setup a Matrix [1] server....&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Thu, 17 Sep 2026 01:40:38 +0000</pubDate>

</item> 
<item>
	<title>Paul Tagliamonte: DESFire EV3</title>
	<guid>https://notes.pault.ag/desfire-ev3/</guid>
	<link>https://notes.pault.ag/desfire-ev3/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/paultag.png&quot; width=&quot;65&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;I’ve &lt;em&gt;long&lt;/em&gt; been interested in hardware key material storage devices. I’ve been
a fan of &lt;a href=&quot;https://github.com/go-piv/go-ykpiv&quot;&gt;yubikeys&lt;/a&gt; (I still remember
when my fancy new NEO-N showed up), &lt;a href=&quot;https://github.com/paultag/go-piv&quot;&gt;PIV&lt;/a&gt;
(and its associated
&lt;a href=&quot;https://github.com/paultag/go-othername&quot;&gt;smattering&lt;/a&gt; of
&lt;a href=&quot;https://github.com/paultag/go-fasc&quot;&gt;additional&lt;/a&gt;
&lt;a href=&quot;https://github.com/paultag/go-cbeff&quot;&gt;fields&lt;/a&gt;),
&lt;a href=&quot;https://github.com/hallowauth/hallow&quot;&gt;SaaS HSMs&lt;/a&gt;,
the &lt;a href=&quot;https://github.com/paultag/go-keyring&quot;&gt;kernel keyring&lt;/a&gt;, some tooling
I’ve fairly satisfied with the design of at prior companies, and of course,
our dear friend, the TPM. All that is not even to mention the scores of exotic
hardware security modules one generally comes across from time to time when
you’re keeping a sharp eye out that you wind up playing with.&lt;/p&gt;
&lt;aside class=&quot;right&quot;&gt;
I have not used any LLMs in the course of this adventure. Not for
writing these posts, and not for this code. The intent here was to learn
more about how DESFire works. LLMs defeat that purpose.
&lt;/aside&gt;
&lt;p&gt;The concept of storing private key material on a disk, or even having it in
RAM has always skeeved me out, so I have a natural inclination to hardware
modules, and how shifting keying material around can change your risks
and threat model(s) in interesting ways.&lt;/p&gt;
&lt;p&gt;I don’t remember when I first came across the
&lt;a href=&quot;https://www.nxp.com/products/MF3DHx3&quot;&gt;MIFARE DESFire EV3&lt;/a&gt;, but a few weeks ago
I did a deep-dive into the state of the art of authentication schemes using
ID cards. My complete overview of what tradeoffs exist is pretty extensive
(and likely not interesting to the vast majority of the world), but the tl;dr
wound up being one of “use PIV” or “use MIFARE DESFire EV3”. I wound up
picking DESFire for a recent project, and figured it’s worth talking
a bit about what I learned, share some thoughts, and some code. That code is
published on &lt;a href=&quot;https://crates.io/crates/desox&quot;&gt;crates.io/desox&lt;/a&gt;, and docs,
as is our custom, may be found at
&lt;a href=&quot;https://docs.rs/desox/latest/desox/&quot;&gt;docs.rs/desox&lt;/a&gt;&lt;/p&gt;
&lt;aside class=&quot;left&quot;&gt;
PIV, while oft-maligned, is exceptional for public key cryptography using
asymmetric keys, and can safely interoperate with x.509. If any of those things
are a hard must, I don&#39;t think that&#39;s going anywhere.
&lt;/aside&gt;
&lt;p&gt;DESFire supports DES (I’m sure most readers saw that one coming), 3DES (I
didn’t bother playing with 3DES at all) or AES-128 (AFAICT always use this?)
keying material. It’s worth noting that the DESFire only supports symmetric
keys and is not designed for public key cryptography, and operates exclusively
using shared symmetric key material. The DESFire EV series use those keys and
related authentication schemes to interact with “files” stored on the on-chip
EEPROM (2k, 4k, 8k, and 16k versions exist), or “applications” (groups of files
and authentication keys).&lt;/p&gt;
&lt;h1 id=&quot;talking-to-a-desfire-ev3&quot;&gt;Talking to a DESFire EV3&lt;/h1&gt;
&lt;p&gt;Interactions with the card are done over NFC (ISO/IEC 14443 Type A), and
commands to/from the card may be in the usual ISO/IEC 7816-4 APDU format, or
“unencapsulated” bytes sent to/from the card are sent using a fixed instruction
set and return code structure – saving a few bytes per message. I’ve opted to
use their undocumented and proprietary format – I found it easier to work
with and with a maximum message of 60 bytes, the savings matter a lot.&lt;/p&gt;
&lt;aside class=&quot;right&quot;&gt;
I keep calling the DESFire messages I implemented &quot;APDU messages&quot; since I have
to use a bunch of API surface saying it is -- but they&#39;re not.
&lt;/aside&gt;
&lt;p&gt;While powered via NFC, the card maintains a small amount of state about the
connection between the reader and the card in its RAM, including if the
session is authenticated or unauthenticated. I’ll dig into how authentication
happens later, but it’s worth knowing that sessions &lt;em&gt;can&lt;/em&gt; become authenticated
using one of the symmetric keys shared by the card and the reader. The vast
majority of the
&lt;a href=&quot;https://docs.rs/desox/0.5.1/desox/enum.Instruction.html&quot;&gt;DESFire commands&lt;/a&gt;
I know about tend to work while either authenticated or unauthenticated,
with a few exceptions (&lt;code&gt;GetUid&lt;/code&gt;, &lt;code&gt;ChangeKey&lt;/code&gt;, and &lt;code&gt;ChangeKeySettings&lt;/code&gt;
for example).&lt;/p&gt;
&lt;p&gt;In general, I found working with this card particularly pleasant. There is a
fair amount of backwards-compatible behavior and multiple methods of
communication that confuse things a bit, but overall, it was better than
average to integrate with. Kudos to the NXP team. If the docs on this chip
were public, things would be orders of magnitude easier – it’s not entirely
clear to my why they’re keeping so much of the interface documentation under
NDA, but it’s the largest knock against the chip, by far.&lt;/p&gt;
&lt;h2 id=&quot;authentication&quot;&gt;Authentication&lt;/h2&gt;
&lt;p&gt;I found a lot of really great resources outlining how the handshake and
protocol works for a DESFire EV3, especially from
&lt;a href=&quot;https://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/&quot;&gt;Ridrix&lt;/a&gt;,
some &lt;a href=&quot;https://www.cardlogix.com/wp-content/uploads/MIFARE-Application-Programming-Guide-for-DESFfire_rev.e.pdf&quot;&gt;public datasheets&lt;/a&gt;
&lt;a href=&quot;https://www.scribd.com/document/683260738/DESFire&quot;&gt;ThrRealRevK&lt;/a&gt;
and posts from &lt;a href=&quot;https://medium.com/@androidcrypto/mifare-desfire-ev3-a-beginner-tutorial-android-java-using-the-desfire-for-android-tools-00aaecb8fa93&quot;&gt;AndroidCrypto&lt;/a&gt;.&lt;/p&gt;
&lt;aside class=&quot;left&quot;&gt;
It&#39;s not super clear to me why all of this is under such heavy NDA, surely
a robust ecosystem is nothing but good?
&lt;/aside&gt;
&lt;p&gt;The gist here is that, because the DESFire only does symmetric key operations,
the key exchange (a type of SKA – Symmetric Key Agreement) uses symmetric keys
to establish a unique session key which is used to sign or encrypt data
exchanged between the reader and the card. I’m not going to get too in-depth
here, since there’s a ton of other resources out there to dig into – but I
will do a quick high-level description to keep this post mostly self-contained.&lt;/p&gt;
&lt;p&gt;The authentication protocol serves two main functions – to verify that both
parties know the same shared secret, as well as to act as a SKA to construct a
new session shared secret key. Here’s a quick overview of how a shared session
key is derived between the reader and the card using our symmetric keys
(&lt;code&gt;AES-128&lt;/code&gt; in the case below).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the reader requests to start authentication with the card (something like
&lt;code&gt;AA 00&lt;/code&gt; to start an AES Authentication handshake with keyslot &lt;code&gt;0x00&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The card will then reply with &lt;code&gt;AF&lt;/code&gt; (a status code that indicates more data
is to follow), followed by 16 bytes (in the case of &lt;code&gt;AES-128&lt;/code&gt;) of encrypted
(using CBC) data.&lt;/li&gt;
&lt;li&gt;The hosts then decrypts this block with the symmetric key from keyslot 0,
returning the card’s session nonce.&lt;/li&gt;
&lt;li&gt;The host generates 16 bytes (usually random) for its session
nonce.&lt;/li&gt;
&lt;li&gt;The host sends an instruction of &lt;code&gt;AF&lt;/code&gt; (indicating a continuation of
the previous command), followed by 32 bytes of encrypted data. When decrypted,
the first 16 bytes are our nonce generated in step #4, followed by the 16 bytes
provided by the card, decrypted in step #3, except where every byte is shifted
to the left by one place (the 0th byte is copied to the end).&lt;/li&gt;
&lt;li&gt;The card will reply with &lt;code&gt;00&lt;/code&gt; indicating a successful operation, followed
by 16 bytes, which when decrypted, is our session nonce from step #4, shifted
to the left by one byte in the same way that we did in step #5 with the card’s
nonce.&lt;/li&gt;
&lt;li&gt;At this point, both the reader and card have confirmed the other party has
the same symmetric secret key. The session is now “authenticated” and a
“session key” is derived using the two nonce blocks. Two hashing keys (K1
and K2) are derived from this key, which is used to maintain an ongoing
&lt;a href=&quot;https://csrc.nist.gov/pubs/sp/800/38/b/upd1/final&quot;&gt;CMAC&lt;/a&gt; hash of the messages
coming and going to/from the card.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From here on out, the session is “authenticated”, and responses from the card
which were previously “plain” will now contain a 8-byte CMAC signature,
which can be used to ensure that the replies in question come from the
active session.&lt;/p&gt;
&lt;p&gt;In my &lt;a href=&quot;https://github.com/paultag/desox-rs/tree/v0.5.4/src/handshake&quot;&gt;implementation of the handshake&lt;/a&gt;
I opted to encode the handshake state into rust types, just so I wouldn’t make
any mistakes. The &lt;code&gt;Handshake&lt;/code&gt; type contains the session internals (session
nonce values, keying state, to include IV, etc). This means the authentication
flow (from within my code) uses the &lt;code&gt;Handshake&lt;/code&gt; struct to generate the commands
to send to the card in order:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// Create a new `Handshake`, and return the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// start auth command (something like `AA 00`)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #66d9ef;&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;color: #a6e22e;&quot;&gt;Handshake&lt;/span&gt;::&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;lt;&lt;/span&gt;Initial&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;gt;&lt;/span&gt;::begin(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; output: &lt;span style=&quot;color: #66d9ef;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #a6e22e;&quot;&gt;mut&lt;/span&gt; [&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; key: [&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;; &lt;span style=&quot;color: #ae81ff;&quot;&gt;16&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; key_id: &lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;) -&amp;gt; (Self, &lt;span style=&quot;color: #f92672;&quot;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After we get a reply back from the card (the encrypted version of the card’s
session nonce, sometimes called &lt;code&gt;Rnd_B&lt;/code&gt; in code I’ve seen), we transition
states from &lt;code&gt;Initial&lt;/code&gt; into &lt;code&gt;HalfOpen&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// Given the card&#39;s encrypted response, generate
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// our session nonce and generate a reply
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// (something that starts with `AF` followed by
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// 32 bytes of encrypted data).
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #66d9ef;&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;color: #a6e22e;&quot;&gt;Handshake&lt;/span&gt;::&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;lt;&lt;/span&gt;Initial&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;gt;&lt;/span&gt;::rnd_b(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; self,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; output: &lt;span style=&quot;color: #66d9ef;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #a6e22e;&quot;&gt;mut&lt;/span&gt; [&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; input: &lt;span style=&quot;color: #66d9ef;&quot;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;) -&amp;gt; (Handshake::&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;lt;&lt;/span&gt;HalfOpen&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;gt;&lt;/span&gt;, &lt;span style=&quot;color: #f92672;&quot;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that we’re “&lt;code&gt;HalfOpen&lt;/code&gt;”, we’re waiting to hear back from the card to ensure
that it, too, can byte-shift our provided nonce. Once we have the card’s reply,
we can check it using our &lt;code&gt;complete&lt;/code&gt; helper, transitioning from &lt;code&gt;HalfOpen&lt;/code&gt; to
&lt;code&gt;Successful&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// Check to ensure that the card replied with
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// our nonce byte-shifted by one place, indicating
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// that they know the symmetric secret in
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// this key slot.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #66d9ef;&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;color: #a6e22e;&quot;&gt;Handshake&lt;/span&gt;::&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;lt;&lt;/span&gt;HalfOpen&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;gt;&lt;/span&gt;::complete(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; self,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; input: &lt;span style=&quot;color: #66d9ef;&quot;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;) -&amp;gt; &lt;span style=&quot;color: #a6e22e;&quot;&gt;Handshake&lt;/span&gt;::&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;lt;&lt;/span&gt;Successful&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;gt;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the &lt;code&gt;Handshake&lt;/code&gt; is successful, the only thing left to do is consume
the &lt;code&gt;Handshake&lt;/code&gt; struct and turn it into the shared session key by running
it through the &lt;a href=&quot;https://github.com/paultag/desox-rs/blob/v0.5.4/src/crypto/kdf.rs&quot;&gt;key derivation function&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// Consume the `Handshake` struct and return the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #e6db74;&quot;&gt;/// new shared session secret key.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #66d9ef;&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;color: #a6e22e;&quot;&gt;Handshake&lt;/span&gt;::&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;lt;&lt;/span&gt;Successful&lt;span style=&quot;color: #f92672;&quot;&gt;&amp;gt;&lt;/span&gt;::into_key(self) -&amp;gt; [&lt;span style=&quot;color: #66d9ef;&quot;&gt;u8&lt;/span&gt;; &lt;span style=&quot;color: #ae81ff;&quot;&gt;16&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From here on out we can use this session key for the remainder of our
interactions with the card – signing messages from (and sometimes to!) the
card, or encrypted messages to and from the card. This key is used in CBC block
mode, where the session IV is updated with the last block of the encrypted
data.&lt;/p&gt;
&lt;h2 id=&quot;unit-testing&quot;&gt;Unit Testing&lt;/h2&gt;
&lt;p&gt;A nice proprietary of the SKA scheme we’re using as part of DESFire is that the
derived session key is actually deterministic if you control your nonce RNG
(ok, actually, pretty true for most key agreements, but anyway), which means it
is possible to capture traffic over the NFC interface, and “replay” the NFC I/O
with cooked RNGs and ensure byte-identical messages and keys are generated.
Within &lt;code&gt;desox-rs&lt;/code&gt; this is called &lt;code&gt;replay&lt;/code&gt; (I’m creative), and I’ve got a few
replay sessions checked into VCS, which exercise a signficant amount fo the API
surface. All were derived from an actual session with a real DESFire card, and
can be updated with a live card and a &lt;code&gt;--cfg&lt;/code&gt; flag.&lt;/p&gt;
&lt;aside class=&quot;left&quot;&gt;
This replay stuff wound up being super dope, it caught a ton of
almost-regressions during the heavy development phases. If I did this again
from scratch -- this would be the first thing I did.
&lt;/aside&gt;
&lt;p&gt;Each &lt;code&gt;replay&lt;/code&gt; file is a set of lines (request-response transactions), each
containing two space-delimited hex encoded NFC messages. For instance,
here’s an authentication handshake in &lt;code&gt;replay&lt;/code&gt; format:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;1a00 afc7bbd82ff8fefae8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;afc6dab54df2278d2952d560821be7e4c3 007d9abe94a9b14748
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The code that generated that exchange came from the test stored adjacent
to that file – a handshake with the default DES key (all zeros), and
an &lt;code&gt;RndA&lt;/code&gt; value hardcoded to &lt;code&gt;32c28fdafd3960de&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #66d9ef;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color: #66d9ef;&quot;&gt;mut&lt;/span&gt; card &lt;span style=&quot;color: #f92672;&quot;&gt;=&lt;/span&gt; card
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; .authenticate_with_rnd_a(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color: #ae81ff;&quot;&gt;0x00&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; Key::Des([&lt;span style=&quot;color: #ae81ff;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #ae81ff;&quot;&gt;8&lt;/span&gt;]),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; Key::Des(hex_literal::&lt;span style=&quot;color: #a6e22e;&quot;&gt;hex!&lt;/span&gt;(&lt;span style=&quot;color: #e6db74;&quot;&gt;&quot;32 c2 8f da fd 39 60 de&quot;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; .&lt;span style=&quot;color: #66d9ef;&quot;&gt;await&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt; .unwrap();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since the card’s &lt;code&gt;RndB&lt;/code&gt; is similarly unchanging (I’m replaying this file every
time), this will always derive the same session key, which means messages
(including encrypted ones or CMAC signed responses) will be identical, as well.
If you’re playing with the DESFire yourself, feel free to grab my &lt;a href=&quot;https://github.com/paultag/desox-rs/tree/main/src/replay&quot;&gt;replay
files&lt;/a&gt; if you need a
“known good” baseline.&lt;/p&gt;
&lt;p&gt;By default this will run using the
&lt;a href=&quot;https://docs.rs/desox/latest/desox/io/struct.MockBackend.html&quot;&gt;MockBackend&lt;/a&gt;,
replaying each file – expecting a byte-identical request, and responding with
the harcoded customary reply. If the code (or test!) needs to change, updating
the tests is done by swapping the &lt;code&gt;MockBackend&lt;/code&gt; out for a real one. Since I
had to do this a bunch during development, running &lt;code&gt;cargo test&lt;/code&gt;
with &lt;code&gt;RUSTFLAGS=&quot;--cfg desox_replay_rw&quot;&lt;/code&gt; will, on run, overwrite the replay
file(s) for the executed test(s), ensuring all line-protocol changes are
explicitly caught and reviewed.&lt;/p&gt;
&lt;h1 id=&quot;observations&quot;&gt;Observations&lt;/h1&gt;
&lt;p&gt;Most commands, even ones which require authentication, are transmitted without
CMAC signature(s) or encryption. &lt;code&gt;CMAC&lt;/code&gt; signatures from the reader to the card
are not really used (except for writes to a file which specifies communication
must be &lt;code&gt;CMAC&lt;/code&gt; signed), ditto for encryption (although that one is used for key
change operations, in addition to file writes on files that specify encrypted
communication must be used). The vast majority of commands take a “plain”
request from the reader, and return a CMAC signed response.&lt;/p&gt;
&lt;aside class=&quot;right&quot;&gt;
I really wish there was a mode or configuration flag I could flip that would
enforce CMAC signatures from the reader to the card.
&lt;/aside&gt;
&lt;p&gt;By my eye, this means that a malicious reader, or something otherwise capable
of holding the card online after communication with an authentic reader is
complete are able to execute privilaged commands (since one can simply ignore
the &lt;code&gt;CMAC&lt;/code&gt; signatures on responses), so long as the command doesn’t require the
reader to provide CMAC signatures (or encryption), or allow the card to power
down.&lt;/p&gt;
&lt;h1 id=&quot;fun-with-desfire&quot;&gt;Fun with DESFire&lt;/h1&gt;
&lt;p&gt;I’ve played around a bit with ways to use the DESFire cards in interesting
configurations, given what they’re capable of. Here’s some half-baked thoughts
I had while mucking around with the cards – these are all poorly thought out
sketches of some things we can do given the specific tradeoffs I see with the
DESFire card. It’s also worth noting that I don’t have any of the actual
documentation, and am not a cryptographic grown-up, so take these sketches with
a massive grain of salt.&lt;/p&gt;
&lt;aside class=&quot;left&quot;&gt;
This stuff is right around when I really miss having asymmetric cryptographic
operations handy.
&lt;/aside&gt;
&lt;p&gt;The first thing that came to mind when implementing this is how the
authentication scheme can shift the boundary of what is and is not trusted
(assuming good secure keying, and provided the key slots and card/application
permissions are configured correctly). Rather than push the key material out to
the machine connected to the NFC reader (“reader machine”), I instead tried
turning the NFC reader and computer into something psuedo-untrusted by “merely”
having it pass messages from the card to a trusted remote system (“remote
machine”). This means that the “reader machine” is exchanging NFC data with the
card, but that data is being decrypted, encrypted and processed by the trusted
“remote machine” – the reader is unable to derive the session key.&lt;/p&gt;
&lt;p&gt;For each of these, I wind up needing to authenticate – so there’s still a few
latent risks, but these can mostly be mitigated by asking for a readbacks of
any changed file(s), setting key permissions carefully, and requesting the
card’s UID via the encrypted channel – all of which would require the
symmetric secrets (which undermine the whole security model if comprimised).&lt;/p&gt;
&lt;aside class=&quot;right&quot;&gt;
This all feels a bit messy at times -- but I have to keep grounding myself
in the threat model -- &quot;if you have the key, you can clone the card (or snoop
the session key)&quot;
&lt;/aside&gt;
&lt;p&gt;This general construction is also subject to a hostile takeover of the
untrusted “reader machine”, since most commands (including destructive ones!)
are sent in “&lt;code&gt;PLAIN&lt;/code&gt;” mode – the reader machine can wait until authentication
is complete and then inject commands into the card and “simply” ignore the CMAC
signatures on responses, severing ties with the remote machine. As such, we
also need to take steps to ensure that the key being used is not one that
allows any access beyond what is allowed. Here were some ideas I sketched out
off the back of this theory.&lt;/p&gt;
&lt;h2 id=&quot;the-second-factor&quot;&gt;The “second-factor”&lt;/h2&gt;
&lt;p&gt;Given some established (and authenticated) connection, part of the initial
authentication flow may use the DESFire card to prove physical control over it
as part of a handshake. This can serve as a second factor during some
authentication flow, requiring physical card presence at a reader to fully
initialize a connection. This does have one glaring downside, however – it’s
phishable. To use this “for real”, we’d need to take some steps to prevent
obvious MITM flows (XOR the NFC messages with the URI as seen by the client?),
but maybe there’s something interesting there.&lt;/p&gt;
&lt;aside class=&quot;left&quot;&gt;
WebAuthN is objectively better in basically every way to this -- this scheme
has some heafty downsides, but also a few interesting properties.
&lt;/aside&gt;
&lt;p&gt;This also has a second interesting attribute – when used as part of a physical
system authentication flow, this becomes a logical place to inject access
control, being able to determine if some person is permitted to operate some
device at that particular time (Is “Joe” current on his Laser Cutter
certifications?) I think of the ideas I landed on, while conceptually
interesting (using an employee id card as a 2FA token, it’s very fast), this
one is the least likely to turn into something real.&lt;/p&gt;
&lt;h2 id=&quot;the-encrypted-cookie&quot;&gt;The “encrypted-cookie”&lt;/h2&gt;
&lt;p&gt;This construction, when paired with an encrypted DESFire file, allows the
“remote machine” to read/write an ’encrypted cookie’ to the card – storing
small amount of encrypted data that the “remote machine” can read/write, but
not the “reader machine”, since this uses an encrypted and authenticated
channel from the “remote machine” directly to the DESFire card, without any
intermediate hosts needing to be &lt;em&gt;fully&lt;/em&gt; trusted. I keep calling this the
“encrypted cookie” in my head because it feels conceptually similar to how Ruby
on Rails and Laravel handles cookies.&lt;/p&gt;
&lt;aside class=&quot;right&quot;&gt;
I never really liked encrypted cookies.
&lt;/aside&gt;
&lt;p&gt;We’d need to take a few extra steps here (for instance, ensure that you read
the cookie back over the encrypted channel after writing to prevent a malicious
reader from dropping writes) to secure the system, but it feels like the
structure of this is definitely decent.&lt;/p&gt;
&lt;h2 id=&quot;the-takeover&quot;&gt;The “takeover”&lt;/h2&gt;
&lt;p&gt;This time, let’s say the computer attached to the NFC reader (“reader machine”)
&lt;em&gt;is&lt;/em&gt; semi-trusted. For this scheme, our trusted “remote machine” and the
“reader machine” pass messages over the network to handle authentication to the
card (as above), where the handshake data is being decrypted, encrypted and
processed by the trusted “remote machine” as usual. However, once the
authentication handshake is complete and a session key has been derived, the
“remote system” return the session key to the “reader machine”, giving it a
one-time-use key and authenticated session to the card.&lt;/p&gt;
&lt;aside class=&quot;left&quot;&gt;
Like a hermit crab.
&lt;/aside&gt;
&lt;p&gt;We need to be careful about global/application permissions and key access
control to files – but in this construction, we can allow the “reader machine”
to take over privileged actions using a scope-limited DESFire key without
handing over the card’s true keying material (preventing cloning of the card).
This can be helpful to ensure messages to/from the card are &lt;em&gt;truely&lt;/em&gt; from the
card (verifying CMAC signatures), enables the “reader machine” to directly
read/write to/from encrypted file(s), but allows the symmetric key material to
remain in as few places as possible – which is critical given compromising
that secret will undermine the security of the entire system.&lt;/p&gt; </description> 
	<pubDate>Tue, 15 Sep 2026 13:25:00 +0000</pubDate>

</item> 
<item>
	<title>Yves-Alexis Perez: IKEv1 protocol disabled in strongSwan package for Debian unstable</title>
	<guid>http://www.corsac.net/?rub=blog&amp;post=1617</guid>
	<link>http://www.corsac.net/?rub=blog&amp;post=1617</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/corsac-planet.png&quot; width=&quot;80&quot; height=&quot;81&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Heads up, Debian IKE/IPsec users.&lt;/p&gt;
&lt;p&gt;Starting with strongSwan &lt;a href=&quot;https://tracker.debian.org/pkg/strongswan&quot; title=&quot;strongSwan page in Debian package tracker&quot;&gt;6.1.0-1&lt;/a&gt; (currently
in Debian unstable and targeted at Debian 14 Forky), the IKEv1
protocol has been disabled. This is aligned with &lt;a href=&quot;https://strongswan.org/blog/2026/09/07/strongswan-6.1.0-released.html&quot; title=&quot;strongSwan 6.1.0 release blog post&quot;&gt;
upstream decision&lt;/a&gt;. Considering IKEv2 is already nearly old
enough to drink in the USA (&lt;a href=&quot;https://datatracker.ietf.org/doc/rfc4306/&quot; title=&quot;RFC 4306 on IETF.org&quot;&gt;RFC 4306 will turn
21&lt;/a&gt; next December) and IKEv1 has weaknesses, the disabling is
long overdue amd will permit upstream to remove some code in the
upcoming years.&lt;/p&gt;
&lt;p&gt;At this point there is no good reason not to migrate to IKEv2
and exposing IKEv1 code in all Debian installation is no longer
relevant. All IKEv1 users using Debian 13 Trixie (either site to
site, gateway or roadwarrior client) should investigate IKEv2
protocol (or other options).&lt;/p&gt;
&lt;p&gt;Note that some plugins have also been disabled upstream for
security/maintenance reasons and we followed suite in Debian. The
Debian relevant ones are: af-alg, led, padlock.&lt;/p&gt; </description> 
	<pubDate>Tue, 15 Sep 2026 07:28:41 +0000</pubDate>
  <author>corsac@debian.org (Yves-Alexis)</author>  
</item> 
<item>
	<title>Reproducible Builds: Supporter spotlight: Jochen Sprickerhof on ... Reproducible Builds!</title>
	<guid>https://reproducible-builds.org/news/2026/09/15/supporter-spotlight-jochen-sprickerhof/</guid>
	<link>https://reproducible-builds.org/news/2026/09/15/supporter-spotlight-jochen-sprickerhof/</link>
     <description>  &lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/news/supporter-spotlight-jochen-sprickerhof/jochen.jpg#right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;big&gt;The Reproducible Builds project &lt;a href=&quot;https://reproducible-builds.org/who/&quot;&gt;relies on several projects, supporters and sponsors&lt;/a&gt; for financial support, but they are also valued as ambassadors who spread the word about our project and the work that we do.&lt;/big&gt;&lt;/p&gt;

&lt;p&gt;This is the &lt;em&gt;ninth&lt;/em&gt; installment in a series featuring the projects, companies and individuals who support the Reproducible Builds project. We started this series by &lt;a href=&quot;https://reproducible-builds.org/news/2020/10/21/supporter-spotlight-cip-project/&quot;&gt;featuring the Civil Infrastructure Platform&lt;/a&gt; project, and followed this up with a &lt;a href=&quot;https://reproducible-builds.org/news/2021/04/06/supporter-spotlight-ford-foundation/&quot;&gt;post about the Ford Foundation&lt;/a&gt; as well as recent ones about &lt;a href=&quot;https://reproducible-builds.org/news/2022/04/14/supporter-spotlight-ardc/&quot;&gt;ARDC&lt;/a&gt;, the &lt;a href=&quot;https://reproducible-builds.org/news/2022/04/26/supporter-spotlight-google-open-source-security-team/&quot;&gt;Google Open Source Security Team (GOSST)&lt;/a&gt;, &lt;a href=&quot;https://reproducible-builds.org/news/2022/05/18/jan-nieuwenhuizen-on-bootrappable-builds-gnu-mes-and-gnu-guix/&quot;&gt;Bootstrappable Builds&lt;/a&gt;, &lt;a href=&quot;https://reproducible-builds.org/news/2022/06/24/supporter-spotlight-hans-christoph-steiner-f-droid-project/&quot;&gt;the F-Droid project&lt;/a&gt;, &lt;a href=&quot;https://reproducible-builds.org/news/2022/12/15/supporter-spotlight-davidawheeler-supply-chain-security/&quot;&gt;David A. Wheeler&lt;/a&gt;, &lt;a href=&quot;https://reproducible-builds.org/news/2023/08/01/supporter-spotlight-simon-butler/&quot;&gt;Simon Butler&lt;/a&gt; and &lt;a href=&quot;https://reproducible-builds.org/news/2024/09/29/supporter-spotlight-kees-cook/&quot;&gt;Kees Cook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today, however, we will be talking with &lt;big&gt;&lt;strong&gt;Jochen Sprickerhof&lt;/strong&gt;&lt;/big&gt;,
one of the newer members of the Reproducible Builds project core team.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant Cascadian: Could you tell me a bit about yourself? What sort of things do you work on?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen Sprickerhof:&lt;/strong&gt;
I am a freelance programmer working on Open Source. Mainly doing &lt;a href=&quot;https://debian.org&quot;&gt;Debian&lt;/a&gt;, &lt;a href=&quot;https://f-droid.org&quot;&gt;F-Droid&lt;/a&gt; and some smaller software projects. In general I made it a habit to look into every software I use and try to fix bugs or add features I need. In Debian, I maintain about 180 packages with topics covering home banking, build systems and robotics. Most of my time, I currently work on &lt;a href=&quot;https://reproduce.debian.net&quot;&gt;&lt;em&gt;reproduce.debian.net&lt;/em&gt;&lt;/a&gt;, where we try to bit-for-bit reproduce the packages distributed by Debian.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: Could you describe the path that lead you to working on reproducible builds?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
I started my Debian journey as a teenager, converting my school to Debian and serving as its system administrator for 13 years. After studying Applied System Science, I joined the university’s robotics labs, where I worked on the &lt;a href=&quot;https://www.ros.org/&quot;&gt;Robot Operating System&lt;/a&gt; (ROS) and the &lt;a href=&quot;https://pointclouds.org/&quot;&gt;Point Cloud Library&lt;/a&gt; (PCL). In the end, I enjoyed programming more than writing papers, so I eventually left academia for a robotics startup. Some years ago, I realized that the open source work I was doing in my spare time was actually the work I cared most about. Nowadays I am really grateful that I can spend my days working on things I find important and have lots of fun with.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: What projects did you recently make big progress on?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
A recent example is &lt;a href=&quot;https://metasnap.debian.net&quot;&gt;&lt;em&gt;metasnap.debian.net&lt;/em&gt;&lt;/a&gt;. It is a ‘meta archive’ of
&lt;a href=&quot;https://snapshot.debian.org&quot;&gt;&lt;em&gt;snapshot.debian.org&lt;/em&gt;&lt;/a&gt; which is itself archive of all packages in Debian. But let
me explain it the other way round: with &lt;em&gt;reproduce.debian.net&lt;/em&gt;, we try to reproduce the packages as they are distributed by the Debian archive. For that, we need the same build environment (compilers, libraries, build tools, etc) that was used by Debian back when the original package was compiled. Luckily, &lt;em&gt;snapshot.debian.org&lt;/em&gt; has all those packages, but they are not easily accessible via &lt;em&gt;apt&lt;/em&gt;, Debian’s package manager. So, &lt;em&gt;metasnap&lt;/em&gt; provides a mapping from a package name and version pair to the APT repo on &lt;em&gt;snapshot.debian.org&lt;/em&gt; needed to download it from. It was created by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;josch&lt;/code&gt; some time ago, and it’s awesome work. But when we tried to reproduce more and more packages on &lt;em&gt;reproduce.debian.net&lt;/em&gt;, we found that some were missing packages from the build environment — even though they where visible on &lt;em&gt;snapshot.debian.org&lt;/em&gt;. We found that &lt;em&gt;metasnap&lt;/em&gt; excluded some archive areas because they where not expected to be needed. Reimporting all the data took more than two months and surfaced a couple more flaws.&lt;/p&gt;

&lt;p&gt;With this fixed, we were able to build more packages, only to find out that &lt;em&gt;metasnap&lt;/em&gt; also needs better support for version numbers. Luckily we were able to rewrite the data in a day instead of starting the import again.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: You have been working on infrastructure to support reproducible builds for a while. Has recent adoption of &lt;em&gt;reproduce.debian.net&lt;/em&gt; into the Debian release tooling changed the focus of your work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
Quite a bit. When we started &lt;em&gt;reproduce.debian.net&lt;/em&gt; in 2024, only around 33% of the packages could be reproduced successfully. Today we are above 98%. Most were not bugs in the packages themselves but in the &lt;em&gt;infrastructure&lt;/em&gt;. Similar to the &lt;em&gt;metasnap&lt;/em&gt; issue I reference above, packages just needed a rebuild because something else, like the toolchain, was fixed in the meantime. In May, people from the Debian release team and the Reproducible Builds project sat together and decided that the overall state is good enough, and now packages that regress on reproducibility are blocked from entering the next Debian release. But that does not mean all the work is on the shoulders of Debian package maintainers. Since then I have been constantly looking at the migration tooling to spot regressions and provide fixes. Furthermore, a couple of maintainers reached out to us for help and I hope more will do so in future.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: What is one small thing you (or others) have not yet gotten to that you would really like to see?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
The central tool to reproduce Debian packages is &lt;em&gt;debrebuild&lt;/em&gt;, also written by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;josch&lt;/code&gt;. Currently it has two ways to retrieve the build dependencies of a package. Either it uses &lt;em&gt;metasnap.debian.net&lt;/em&gt; (as explained above), or it can access the Debian &lt;em&gt;unstable&lt;/em&gt; APT repository directly. This allows to test packages locally before everything is indexed on &lt;em&gt;metasnap&lt;/em&gt; by compiling against Debian &lt;em&gt;unstable&lt;/em&gt;. But actually there are many other APT repositories to query, like Debian stable or even derivatives. Adding support for an optional list of APT repositories in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debrebuild&lt;/code&gt; would be great. That would also be a big step to support reproducing other Debian based distributions.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: … and one &lt;em&gt;big&lt;/em&gt; thing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
It would be great to integrate &lt;em&gt;metasnap.debian.net&lt;/em&gt; into &lt;em&gt;snapshot.debian.org&lt;/em&gt;. There is some discussion on it already in Debian bug &lt;a href=&quot;https://bugs.debian.org/650783&quot;&gt;#650783&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: What are the tools you use the most?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
According to my &lt;em&gt;fish&lt;/em&gt; shell history:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ history | cut -d&#39; &#39; -f1 | sort | uniq -c | sort -nr | head -10
  36199 git
  20941 vi
  12271 rm
   8599 cd
   7917 ls
   6407 apt
   5631 grep
   4249 mv
   3655 dpkg
   2873 cp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: So, is the &lt;em&gt;fish&lt;/em&gt; shell reproducible? I remember it did not used to be…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
You can check for yourself — &lt;a href=&quot;https://reproduce.debian.net/excuses.html?source_name=fish&quot;&gt;it was last time I checked&lt;/a&gt;. But looking through the other commands, &lt;a href=&quot;https://reproduce.debian.net/excuses.html?source_name=neovim&quot;&gt;&lt;em&gt;neovim&lt;/em&gt; sadly is not&lt;/a&gt;. I hope we can fix that in future.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: Oh, that’s a nice URL to check for reproducible package… you can just pass the source package name to check the current results?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
Yes. Another one is &lt;a href=&quot;https://udd.debian.org/reproducibility/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;udd.debian.org/reproducibility/&lt;/code&gt;&lt;/a&gt;, where you
can list all packages of a Debian maintainer. It also lists source reproducibility and has nice filters as well.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: What tools do you use specifically working on reproducible builds?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
I don’t have statistics for that, but I would say &lt;em&gt;sbuild&lt;/em&gt; to build the package, &lt;em&gt;debrebuild&lt;/em&gt; to reproduce it, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diffoscope&lt;/code&gt; to analyze the differences. Obviously I also need run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apt source &amp;lt;package&amp;gt;&lt;/code&gt; or use &lt;em&gt;git-buildpackage&lt;/em&gt; to get the sources and all the tools I mentioned above.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: So how many packages are left to build reproducibly, and once those are finished, what is next?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
Right now, &lt;em&gt;reproduce.debian.net&lt;/em&gt; shows over 98% reproducibility, though there are still over 650 package left and some will probably need a lot of work. But actually I think making packages reproducible is just the first step. For me, this is a project to build confidence in the system. To reproduce a package we have two parts: the source of the package and the build environment. Fixing the packages means gaining confidence in the first part but we still rely on the individual build environments for each package as we need to use the same compiler that was used when the package was build initially. Because of this, we have to keep around every historical version of all toolchain packages. I really would like to remove this extra archive, which means we would have to rebuild all of Debian around release time. I am dreaming of a Debian release where you could bit-for-bit reproduce every package just from the released versions. Due to how Debian works, however, this is not a trivial rebuild and it would need some work on the infrastructure. By the way, initially there was a third component to pay attention to: any connection to the outside world during the build. Luckily we fixed the Debian build daemons to not allow network connections during the build some time ago.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vagrant: Thanks for all that work, and taking the time to tell us a bit about yourself!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jochen:&lt;/strong&gt;
Thanks a lot for the interview!&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;For more information about the Reproducible Builds project, please see our website at
&lt;a href=&quot;https://reproducible-builds.org/&quot;&gt;reproducible-builds.org&lt;/a&gt;. If you are interested in
ensuring the ongoing security of the software that underpins our civilisation
and wish to sponsor the Reproducible Builds project, please reach out to the
project by emailing
&lt;a href=&quot;mailto:contact@reproducible-builds.org&quot;&gt;contact@reproducible-builds.org&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt; </description> 
	<pubDate>Tue, 15 Sep 2026 03:54:00 +0000</pubDate>

</item> 
<item>
	<title>Reproducible Builds: Reproducible Builds in August 2026</title>
	<guid>https://reproducible-builds.org/reports/2026-08/</guid>
	<link>https://reproducible-builds.org/reports/2026-08/</link>
     <description>  &lt;p class=&quot;lead&quot;&gt;&lt;strong&gt;Welcome to the August 2026 report from the &lt;a href=&quot;https://reproducible-builds.org&quot;&gt;Reproducible Builds&lt;/a&gt; project!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://reproducible-builds.org/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/reproducible-builds.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our reports, we try to outline the most important things that we have been up to over the past month. As a quick recap about what problem our project intends to solve, whilst anyone may inspect the source code of free software for malicious flaws, almost all software is distributed to end users as pre-compiled binaries. The motivation behind the reproducible builds effort is to ensure no flaws have been introduced during this compilation process by promising identical results are always generated from a given source, thus allowing multiple third-parties to come to a consensus on whether a build was compromised or not.&lt;/p&gt;

&lt;p&gt;In this month’s report, we cover:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#new-updated-sbom-specification-from-cisagov&quot;&gt;New updated SBOM specification from CISA.gov&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#lwn-on-bootstrappable-builds-at-fossy-2026&quot;&gt;LWN on Bootstrappable builds at FOSSY 2026&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#whats-missing-to-have-reproducible-builds-on-pypi&quot;&gt;”What’s missing to have reproducible builds on PyPI?”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#distribution-work&quot;&gt;Distribution work&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#unreproducible-builds-under-erofs-filesystem-fixed&quot;&gt;Unreproducible builds under EROFS filesystem fixed&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#tool-and-documentation-development&quot;&gt;Tool and documentation development&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#six-new-scholarly-papers&quot;&gt;Six new scholarly papers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/blog/index.rss#patches&quot;&gt;Patches&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;new-updated-sbom-specification-from-cisagov&quot;&gt;New updated SBOM specification from CISA.gov&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.cisa.gov/sites/default/files/2026-07/2026_cisa_sbom_minimum_elements_508c.pdf&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/2026_cisa_sbom_minimum_elements_508c.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Cybersecurity_and_Infrastructure_Security_Agency&quot;&gt;CISA&lt;/a&gt;, the Cybersecurity and Infrastructure Security Agency of the U.S. government published some the joint guidance entitled &lt;a href=&quot;https://www.cisa.gov/sites/default/files/2026-07/2026_cisa_sbom_minimum_elements_508c.pdf&quot;&gt;&lt;em&gt;Minimum Elements for a Software Bill of Materials&lt;/em&gt;&lt;/a&gt; (SBOM), which updates and supersedes the baseline 2021 version covered in previous editions of these reports.&lt;/p&gt;

&lt;p&gt;Whilst &lt;a href=&quot;https://www.cisa.gov/sites/default/files/2026-07/2026_cisa_sbom_minimum_elements_508c.pdf&quot;&gt;the PDF&lt;/a&gt; is worth skimming, the interesting changes include that the specification now mandates standard cryptographic hashes: unlike earlier standards that allowed hash omission or manifest-only parsing, hashes must be computed from the output. This is is important for reproducible builds, as it ensures the recording of the metadata required to demonstrate the shipped software matches the build output precisely where applicable. In addition, where the top-level only dependency limitation that was present in the 2021 version has been removed in favour of complete coverage with no minimum depth. That is, SBOMs are expected to reflect all linked libraries, vendored dependencies and other build-time inclusions.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;lwn-on-bootstrappable-builds-at-fossy-2026&quot;&gt;LWN on Bootstrappable builds at FOSSY 2026&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://lwn.net/Articles/1088279/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/fossy-sample-sm.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the “Toolchains and Other Development Tools” track at &lt;a href=&quot;https://sfconservancy.org/&quot;&gt;Software Freedom Conservancy&lt;/a&gt;’s &lt;a href=&quot;https://2026.fossy.ca/&quot;&gt;FOSSY 2026&lt;/a&gt; in British Columbia, Canada, Timothy Sample gave a presentation on &lt;a href=&quot;https://bootstrappable.org/&quot;&gt;bootstrappable builds&lt;/a&gt;. This &lt;a href=&quot;https://lwn.net/Articles/1088279/&quot;&gt;presentation was then covered&lt;/a&gt; in a &lt;a href=&quot;https://lwn.net/&quot;&gt;Linux Weekly News&lt;/a&gt; article by Jake Edge entitled &lt;a href=&quot;https://lwn.net/Articles/1088279/&quot;&gt;&lt;em&gt;Bootstrappable builds: how and why&lt;/em&gt;&lt;/a&gt;, which serves as an excellent introduction to the concept:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The basic idea behind bootstrappable builds is to create a system that can be built without relying on pre-built artifacts. “Can we go from zero to the modern day without having to just assume the existence of these already-built-for-us artifacts?” The classic recipe for yogurt requires some yogurt to start the process, which is like how we normally build a C compiler today—we start with an existing C compiler binary. You might think about making sourdough bread with your grandmother’s starter brought over from the old country; “we’re basically making C compilers with Dennis Ritchie’s starter carried over from Bell Labs”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The article, which goes on to cover GNU Mes and other projects that overlap with Reproducible Builds, also has &lt;a href=&quot;https://lwn.net/Articles/1088279/#Comments&quot;&gt;a number of thought-provoking comments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;whats-missing-to-have-reproducible-builds-on-pypi&quot;&gt;”&lt;a href=&quot;https://snarky.ca/whats-missing-to-have-reproducible-builds-on-pypi/&quot;&gt;&lt;em&gt;What’s missing to have reproducible builds on PyPI?&lt;/em&gt;&lt;/a&gt;”&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://snarky.ca/whats-missing-to-have-reproducible-builds-on-pypi/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/pypi.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Core Python developer, &lt;a href=&quot;https://snarky.ca/&quot;&gt;Brett Cannon&lt;/a&gt; wrote an interesting blog post this month addressing &lt;a href=&quot;https://snarky.ca/whats-missing-to-have-reproducible-builds-on-pypi/&quot;&gt;&lt;em&gt;What’s missing to have reproducible builds on PyPI&lt;/em&gt;&lt;/a&gt;, the &lt;a href=&quot;https://pypi.org/&quot;&gt;official public repository for third-party Python software packages&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The reason I like the idea of making reproducible builds work is that I think it can be done in such a way as to not require any work on the part of the producer of a distribution (which is a technical term for sdists or wheels, i.e., the people who upload stuff to PyPI), and thus make reproducible builds very low-friction for people to opt into supporting. [&lt;a href=&quot;https://snarky.ca/whats-missing-to-have-reproducible-builds-on-pypi/&quot;&gt;…&lt;/a&gt;]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Brett goes on to outline “What’s missing from the specs” and how reproducibility might be visible on PyPI to consumers:&lt;/p&gt;

&lt;p&gt;Assuming all of this comes to pass and we record the where the source code is that went into a distribution and the software used to make the distribution, how do we make it useful to people? Does every person who cares about having a secure supply chain have to rebuild everything they use themselves? Is there some way for even people who don’t care about this stuff to benefit? [&lt;a href=&quot;https://snarky.ca/whats-missing-to-have-reproducible-builds-on-pypi/&quot;&gt;…&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;distribution-work&quot;&gt;Distribution work&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://debian.org/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/debian.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Debian&lt;/strong&gt; this month, 23 reviews of Debian packages were added, 28 were updated and 27 were removed this month adding to &lt;a href=&quot;https://tests.reproducible-builds.org/debian/index_issues.html&quot;&gt;our knowledge about identified issues&lt;/a&gt;. A number of issue types have been updated as well, such as the addition of a new toolchain issue related to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-traitlets&lt;/code&gt; [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-notes/commit/666e1847&quot;&gt;…&lt;/a&gt;], and the note for an existing issue related to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;texi2html&lt;/code&gt; was updated as well [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-notes/commit/8c55be8f&quot;&gt;…&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.opensuse.org/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/opensuse.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, Bernhard M. Wiedemann posted another &lt;a href=&quot;https://www.opensuse.org/&quot;&gt;&lt;strong&gt;openSUSE&lt;/strong&gt;&lt;/a&gt; &lt;a href=&quot;https://lists.opensuse.org/archives/list/factory@lists.opensuse.org/thread/C7BCS4OC2XPR5ZNOEXCJGP6NXL2W5BNT/&quot;&gt;monthly update&lt;/a&gt; for their reproducibility work there.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;unreproducible-builds-under-erofs-filesystem-fixed&quot;&gt;Unreproducible builds under EROFS filesystem fixed&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://fosstodon.org/@martinpitt&quot;&gt;Martin Pitt&lt;/a&gt; reported on &lt;a href=&quot;https://fosstodon.org/&quot;&gt;Fosstodon&lt;/a&gt; that they had &lt;a href=&quot;https://fosstodon.org/@martinpitt/117034829700534836&quot;&gt;identified an issue&lt;/a&gt; where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkfs&lt;/code&gt; (“make filesystem”) command for the &lt;a href=&quot;https://en.wikipedia.org/wiki/EROFS&quot;&gt;EROFS&lt;/a&gt; (Enhanced Read-Only File System) subsystem of the Linux kernel did not have sorted &lt;a href=&quot;https://en.wikipedia.org/wiki/Extended_file_attributes&quot;&gt;extended file attributes&lt;/a&gt;, leading to reproducible builds.&lt;/p&gt;

&lt;p&gt;Thankfully, Martin also reported that &lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git/commit/?id=37fc4113694e1c9690bd871aefe91f55bf8bd029&quot;&gt;they had fixed this in a commit to the kernel&lt;/a&gt; which “order[s] each inode’s xattrs by name so that images stay reproducible”. [&lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git/commit/?id=37fc4113694e1c9690bd871aefe91f55bf8bd029&quot;&gt;…&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;tool-and-documentation-development&quot;&gt;Tool and documentation development&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://diffoscope.org/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/diffoscope.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://diffoscope.org&quot;&gt;&lt;strong&gt;diffoscope&lt;/strong&gt;&lt;/a&gt; is our in-depth and content-aware diff utility that can locate and diagnose reproducibility issues. This month, Chris Lamb made a number of changes, including preparing and uploading versions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;327&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;328&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;329&lt;/code&gt; to Debian. In particular, he ensured that &lt;em&gt;diffoscope&lt;/em&gt; did not require &lt;em&gt;python3-guestfs&lt;/em&gt; in the autopkgtests on 32-bit architectures in order to fix Debian bug (&lt;a href=&quot;https://bugs.debian.org/1144372&quot;&gt;#1144372&lt;/a&gt;) [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/diffoscope/commit/5440dd50&quot;&gt;…&lt;/a&gt;]. Colin Watson made an additional change, handling a potentially missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openssh-client&lt;/code&gt; package when running the autopkgtests [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/diffoscope/commit/a4fd009a&quot;&gt;…&lt;/a&gt;], and Jochen Sprickerhof made a similar change to cope with missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpio&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qemu-img&lt;/code&gt; functionality [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/diffoscope/commit/ae4f6f86&quot;&gt;…&lt;/a&gt;] whilst also updating the XML comparator to be considered when comparing SVG images [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/diffoscope/commit/c7f23bb0&quot;&gt;…&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://reproducible-builds.org/&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/website.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yet again, there were a number of improvements made to &lt;a href=&quot;https://reproducible-builds.org/&quot;&gt;&lt;strong&gt;our website&lt;/strong&gt;&lt;/a&gt; this month as well. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Chris Lamb added draft for a &lt;a href=&quot;https://reproducible-builds.org/news/2026/08/12/reproducible-builds-summit-in-gothenburg/&quot;&gt;Gothenburg summit&lt;/a&gt;-related news article. [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/126f1774&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/194c4f24&quot;&gt;…&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Holger Levsen then published &lt;a href=&quot;https://reproducible-builds.org/news/2026/08/12/reproducible-builds-summit-in-gothenburg/&quot;&gt;the same article&lt;/a&gt;. [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/12265a52&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/3be2ff73&quot;&gt;…&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Lastly, a large number of commits were pushed comprising an interview with Reproducible Builds developer Jochen Sprickerhof to be published within the next week. [&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/22f405e8&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/f11b768a&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/953236c7&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/60aa39b1&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/0eb0aa3c&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/53682fea&quot;&gt;…&lt;/a&gt;][&lt;a href=&quot;https://salsa.debian.org/reproducible-builds/reproducible-website/commit/11cd8461&quot;&gt;…&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;six-new-scholarly-papers&quot;&gt;Six new scholarly papers&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2607.21888&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/paper-2607.21888.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jens Dietrich, Spencer Sun, Tim W. White and Behnaz Hassanshahi (the result of a collaboration between &lt;a href=&quot;https://www.wgtn.ac.nz/&quot;&gt;Victoria University of Wellington&lt;/a&gt; and &lt;a href=&quot;https://www.oracle.com/anz/&quot;&gt;Oracle Australia&lt;/a&gt; published a paper this month entitled &lt;a href=&quot;https://arxiv.org/abs/2607.21888&quot;&gt;&lt;em&gt;No Snake Oil: Verifying Python Package Builds&lt;/em&gt;&lt;/a&gt;. Drawing on the metaphor of “snake oil”, that is, a fake or ineffective medicine or solution sold with exaggerated claims of curing or fixing everything, the authors write that&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Two tools that are designed to automate [PyPI] rebuilds and run them at scale are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;macaron&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oss-rebuild&lt;/code&gt;. We study 12,180 popular releases from PyPI and find that the byte-for-byte equivalence rate is generally low. We analyse the reasons why they produce different wheels, and find that equivalence between the original and rebuilt wheels can often still be established, preserving most of the guarantees users expect from rebuildable releases. &lt;strong&gt;We present and evaluate daleq4py, a tool to establish the equivalence of Python wheels through the kernel of a normalisation function that is based on provenance-preserving datalog rules. Experimental results show that daleq4py substantially expands the set of rebuilds that can be accepted as equivalent.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;a href=&quot;https://arxiv.org/pdf/2607.21888&quot;&gt;full PDF of their paper&lt;/a&gt; can be viewed online, and Jens Dietrich to &lt;a href=&quot;https://lists.reproducible-builds.org/listinfo/rb-general/&quot;&gt;our mailing list&lt;/a&gt; to &lt;a href=&quot;https://lists.reproducible-builds.org/pipermail/rb-general/2026-August/004146.html&quot;&gt;announce the availability&lt;/a&gt; of both the paper and the &lt;a href=&quot;https://github.com/binaryeq/daleq4py/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;daleq4py&lt;/code&gt; tool&lt;/a&gt; itself.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2607.26719&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/paper-2607.26719.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dimitri Kokkonis, Michaël Marcozzi and Stefano Zacchiroli published an article this month titled &lt;a href=&quot;https://arxiv.org/abs/2607.26719&quot;&gt;&lt;em&gt;Not In My Git Yard: Catching Backdoors at Commit and Release Time&lt;/em&gt;&lt;/a&gt; on the topic of “code-level backdoors” — that is, “stealthy code changes that grant hidden privileges via secret triggers”. These issues:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;… pose a persistent threat to opensource software. Known attempts to inject such backdoors into widely used projects through malicious commits, tampered release packages, or compromised third-party dependencies, were stopped only by luck and manual review. Existing Continuous Integration (CI) pipelines cannot detect these attacks, and downstream binary analysis tools require substantial manual effort. &lt;strong&gt;In this work, we present Lily, an automated approach that strengthens open-source development and release processes against backdoor injection. Lily integrates a backdoor detection mechanism into (1) CI pipelines to block malicious commits, and (2) release vetting workflows to prevent tampered releases or compromised dependencies from entering large ecosystems, such as Linux distributions.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;a href=&quot;https://arxiv.org/pdf/2607.26719&quot;&gt;full PDF&lt;/a&gt; can be read online.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2608.20678&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/paper-2608.20678.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ranindya Paramitha and Laurie Williams of North Carolina State University along with  Christian Kästner of Carnegie Mellon University published a paper this month with the title of &lt;a href=&quot;https://arxiv.org/abs/2608.20678&quot;&gt;&lt;em&gt;The Software Supply Chain as a Market for Lemons: A Multivocal Review of Trust Signal Collapse&lt;/em&gt;&lt;/a&gt;. (A &lt;a href=&quot;https://en.wikipedia.org/wiki/Lemon_(automobile)&quot;&gt;“lemon”&lt;/a&gt; in American English, is a vehicle that “turns out to have several manufacturing defects”.) Their abstract is as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Practitioners evaluating open-source dependencies rely on cheap trust signals, e.g., stars, download counts, and contributor activity, as substitutes for direct code inspection, assuming those signals reflect genuine trustworthiness. Prior work has documented individual signal gaming, but the landscape of collapses across all dependency-adoption signals, as well as the ecosystem’s response, remains unexplored. &lt;strong&gt;The goal of this study is to aid software practitioners in understanding the reliability of dependency adoption trust signals, such as download counts and contributor activity, by conducting a multivocal review of 252 Google Search sources and 870 Reddit threads.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Worryingly, after their review, the authors conclude that “cheap trust signals collapse under three simultaneous forces: adversarial manipulation, gaming techniques indistinguishable from legitimate behavior, and non-adversarial AI-driven inflation.”&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://arxiv.org/pdf/2608.20678&quot;&gt;full PDF of the paper&lt;/a&gt; is available online.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2607.24888&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/paper-2607.24888.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Julien Malka, Aman Sharma, Martin Monperrus, Stefano Zacchiroli and Théo Zimmermann published a paper this month on &lt;a href=&quot;https://arxiv.org/abs/2607.24888&quot;&gt;&lt;em&gt;Trusting-Trust Attack against an Entire Linux Distribution through Binary Manipulation&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Backdoor_(computing)#Compiler_backdoors&quot;&gt;Ken Thompson’s trusting-trust attack&lt;/a&gt;, in which a compromised compiler backdoors the programs it builds and reproduces the backdoor in subsequent rebuilds of itself, is widely regarded as a threat specific to compilers. We show that it is not. &lt;strong&gt;We construct a complete trusting-trust attack around GNU &lt;em&gt;strip&lt;/em&gt;, an ordinary build utility that neither inspects nor generates source code, using only manipulations of finished ELF files.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Scarily, in the authors’ example, “a single tampered &lt;em&gt;strip&lt;/em&gt; in the binary seed implants a payload that propagates from one generation of strip to the next and survives into the final standard environment after the seed leaves the dependency closure […] without failures and backdoors”.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://arxiv.org/pdf/2607.24888&quot;&gt;full PDF of the paper&lt;/a&gt; is available for download online.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2608.27125&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/paper-2608.27125.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mehdi Keshanimm, Amirhossein Rahmati, Mohammad Hossein Aref and Abbas Heydarnoori published a paper that is currently under review at &lt;em&gt;Emperical Software Engineering&lt;/em&gt; titled &lt;a href=&quot;https://arxiv.org/abs/2608.27125&quot;&gt;&lt;em&gt;AROMA+: A Study of Factors Affecting Reproducible Builds in the Maven Ecosystem&lt;/em&gt;&lt;/a&gt;. (&lt;a href=&quot;https://maven.apache.org/&quot;&gt;Maven&lt;/a&gt; is a/the build automation tool used for Java projects.) In their paper, the authors note that&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[…] reusing external software in a project presents a security risk when the source of the component is unknown or the consistency of a component cannot be verified. The &lt;a href=&quot;https://en.wikipedia.org/wiki/SolarWinds#2019%E2%80%932020_supply_chain_attacks&quot;&gt;SolarWinds attack&lt;/a&gt; serves as a popular example in which the injection of malicious code into a library affected thousands of customers and caused a loss of billions of dollars. […] Our research aims to support [reproducibility] efforts in the Maven ecosystem through automation. We investigate the feasibility of automatically finding the source code of a library from its Maven release and recovering information about the original release environment. Our tool, AROMA+, can obtain this critical information from the artifact and the source repository through several heuristics and we use the results for reproduction attempts of packages on Maven Central.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;a href=&quot;https://arxiv.org/pdf/2608.27125&quot;&gt;full PDF of their article&lt;/a&gt; can be downloaded online.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2608.18180&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://reproducible-builds.org/images/reports/2026-08/paper-2608.18180.png#right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, Oreofe Solarin, Kelechi Kalu, James C. Davis and Paschal Amusuo published a paper this month titled &lt;a href=&quot;https://arxiv.org/abs/2608.18180&quot;&gt;&lt;em&gt;Reproducibility is Not Enough: Artifact Verifiability in Decentralized-Build Package Ecosystems&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[A]rtifact verification requires more than deterministic builds: a verifier must also recover the source state, build environment, dependencies, and build instructions that produced the artifact. Decentralized-build ecosystems make this difficult because artifacts are produced through heterogeneous tools, maintainer-controlled workflows, and fragmented metadata. As a result, it remains unclear how often artifacts in these ecosystems can be independently verified. &lt;strong&gt;This paper studies artifact verifiability across four popular decentralized-build package ecosystems. We define an independent verifier model that relies only on registry-derivable metadata and an artifact comparison model with tiered equivalence levels. We implement these models in an Artifact Verification Pipeline and use it to measure artifact verifiability across the target ecosystems.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The authors conclude that “beyond build determinism, verifiability is limited by missing source and build metadata, implicit release transformations, and unconventional build practices”.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://arxiv.org/pdf/2608.18180&quot;&gt;PDF&lt;/a&gt; of their paper can be reviewed online.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;patches&quot;&gt;Patches&lt;/h3&gt;

&lt;p&gt;The Reproducible Builds project detects, dissects and attempts to fix as many currently-unreproducible packages as possible. We endeavour to send all of our patches upstream where applicable or possible. This month, we wrote a large number of such patches, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Bernhard M. Wiedemann:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugzilla.opensuse.org/show_bug.cgi?id=1274324&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Botan&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1371954&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rivet&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1374641&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1370073&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ceph&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/pop-os/xdgen/pull/2&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cosmic/xdgen&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1374640&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpio&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/dlang/dmd/pull/23746&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmd&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1374399&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dvgt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://git.enlightenment.org/enlightenment/efl/pulls/148&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;efl&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1375163&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;firefox-esr&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/fritzing/fritzing-app/pull/4336&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fritzing&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108534#c3&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcc/esbuild&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1373692&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git-annex&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1373163&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go1.27/esbuild&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1370297&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gputils/sdcc&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/OSGeo/grass/pull/7849&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grass&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1370260&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gri&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1369973&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java-21-openj9&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1369976&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java-25-openj9&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1370294&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ksh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1374284&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm22&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/llvm/llvm-project/pull/219384&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/llvm/llvm-project/pull/219388&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/ozwaldorf/lutgen-rs/pull/46&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lutgen&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1373751&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maxima&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1371702&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mingw64-filesystem&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://invent.kde.org/network/neochat/-/merge_requests/2987&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;neochat&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/openSUSE/obs-build/pull/1164&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;obs&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1373241&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-PyMuPDF&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1373864&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-gguf&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1371636&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-langgraph&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1369446&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-pook&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1369499&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-pyzmq&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1371724&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-xgrammar&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1373248&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-xlsx2csv&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1370201&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qt6-tools&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1371634&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbcl&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1374393&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scons&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/VirtualBox/virtualbox/pull/827&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualbox&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://gitlab.com/wvermin/xpenguins/-/merge_requests/1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpenguins&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/zabbix/zabbix/pull/184&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zabbix&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Chris Lamb:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143615&quot;&gt;#1143615&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/keychain&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keychain&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143616&quot;&gt;#1143616&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/python-nameparser&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python-nameparser&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143617&quot;&gt;#1143617&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/lcov&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lcov&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1144065&quot;&gt;#1144065&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/displaycal-py3&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;displaycal-py3&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1144066&quot;&gt;#1144066&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/redmine&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redmine&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1144407&quot;&gt;#1144407&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/django-htmx&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;django-htmx&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1144409&quot;&gt;#1144409&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/pybdsf&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pybdsf&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1145914&quot;&gt;#1145914&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/golang-github-adamkorcz-go-fuzz-headers-1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;golang-github-adamkorcz-go-fuzz-headers-1&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1145915&quot;&gt;#1145915&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/googletest&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;googletest&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Jochen Sprickerhof:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1145443&quot;&gt;#1145443&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/cross-toolchain-base&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cross-toolchain-base&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1146088&quot;&gt;#1146088&lt;/a&gt; filed against &lt;a href=&quot;https://tracker.debian.org/pkg/ferret-vis&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ferret-vis&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Robin Candau:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://codeberg.org/aelinden/BashBurn/pulls/1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bashburn&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/LMMS/lmms/pull/8494&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LMMS&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Werner Fink:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://build.opensuse.org/request/show/1364197&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p class=&quot;small&quot;&gt;If you are interested in contributing to the project, please visit our &lt;a href=&quot;https://reproducible-builds.org/contribute/&quot;&gt;&lt;em&gt;Contribute&lt;/em&gt;&lt;/a&gt; page on our website.&lt;/p&gt; </description> 
	<pubDate>Fri, 11 Sep 2026 10:12:50 +0000</pubDate>

</item> 
<item>
	<title>Matthias Klumpp: JPEG-XL as default in AppStream, and better media processing</title>
	<guid>https://blog.tenstral.net/?p=2121</guid>
	<link>https://blog.tenstral.net/2026/09/jpeg-xl-appstream-and-better-media-processing.html</link>
     <description>  &lt;p class=&quot;wp-block-paragraph&quot;&gt;Two weeks ago, I released AppStream 1.2.0. This release contains a lot of great changes, but one of the most important ones concerns how media are being handled, and AppStream’s default image export format.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;&lt;a href=&quot;https://www.freedesktop.org/software/appstream/docs/&quot;&gt;AppStream&lt;/a&gt; is a Freedesktop metadata standard to describe software components. That can be anything from system services over fonts to console and graphical applications. AppStream metadata is supposed to give users enough information to decide whether they want to install a piece of software, to represent that piece of software, and to give the operating system enough information to decide whether a software component should be installed automatically and (to some extent) what capabilities and relations it has, to provide the user with sensible options.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Especially for the first two goals, and especially for GUI applications, AppStream supports icons and screenshots, which are used to showcase applications. Today, AppStream is used by all kinds of services, from Linux distributions over firmware updates to Flatpak and desktops directly. AppStream’s original design however comes from the perspective of Linux distributions in 2011, where you may want to browse the software catalog offline, without delay, and without pinging an external server (which could be a privacy concern).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Therefore, a common way to deploy an AppStream-enabled software repository is to ship all icons of all applications in the repository to the user as part of the repository metadata download. AppStream does support remote icon downloads nowadays, and for a while I thought that this would become the default eventually. However, especially in today’s world, having a bandwidth-saving, instantly responsive, privacy-protecting application browsing experience seems more important that ever.&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;PNG images are great!&lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;The only format that AppStream supports for icons &lt;strong&gt;and&lt;/strong&gt; screenshots (which are downloaded on-demand from your distributor’s CDN) has always been exclusively &lt;a href=&quot;https://en.wikipedia.org/wiki/PNG&quot;&gt;PNG&lt;/a&gt;. PNG images are perfect for icons, because they compress well (especially for common icon shapes), are fast and simple to load, and can be loaded anywhere, by any toolkit or webbrowser. They also ensure we deliver faithful screenshot images, even though we may have scaled or re-rendered them. Still though, PNG images are less great for screenshots, as they are not very efficient, which puts strain on any CDN that has to deliver them, as well as on people’s internet connections when browsing screenshots. Having smaller thumbnails alleviates that problem a little, but does not fully solve it.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;But even for icons, PNG could be improved upon: In many cases, icons are re-downloaded with the repository metadata again and again, so having a large icon tarball adds up to the data transferred during metadata refreshes. AppStream also now supports large 128x128px icons, which nobody in 2012 expected we would need, adding even more data that will be re-downloaded. Saving some space here translates directly to lower bandwidth costs as well as faster downloads for users.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;To improve PNG file sizes, the AppStream Compose library, which handles all image processing and metadata catalog composition, was running &lt;a href=&quot;https://optipng.sourceforge.net/&quot;&gt;optipng&lt;/a&gt; on all generated PNG images. That does create smaller PNG images, but they were still relatively large compared to other image formats.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;For a long time though, there was no alternative to PNG images for icons: There was no lossless image compression format that could give us the same quality as PNG images and that was also widely supported.&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;JPEG-XL vs PNG in AppStream&lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Since 2021 we have &lt;a href=&quot;https://jpegxl.info/&quot;&gt;JPEG-XL&lt;/a&gt; (JXL), which offers a true lossless mode with often better compression than PNG. The issue was that JPEG-XL wasn’t widely supported. Then, in 2025, the PDF Association selected JPEG-XL as the preferred image format for HDR images in PDFs, and now we are finally getting browser support and more ubiquitous availability of the format (you can try it right now in Firefox!).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;For screenshots, using JXL’s lossy mode, it has obvious and extreme size advantages over PNG, so supporting JXL or WebP for screenshot images was an obvious choice. If JXL would support the lossless case very well as well though, we could serve many use cases with the same exported image format, which is very attractive to me.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;So, the obvious next question was whether it was worth the pain of switching the icon format, so I did some measurements on real icons. For that I used the AppStream component icon pool that Debian Unstable ships, which is almost 5000 application icons of various sizes, and converted them to PNG:&lt;/p&gt;



&lt;div&gt;
&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;Icon size&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;Icons&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;PNG total&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;JXL total&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;Pool saved&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;PNG avg&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;JXL avg&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;Median saved&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;Mean saved&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;  Worst&lt;/th&gt;&lt;th align=&quot;right&quot;&gt; Best&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;Larger as JXL&lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;48×48    &lt;/td&gt;&lt;td align=&quot;right&quot;&gt; 1544&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;  3.7 MiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;  3.0 MiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;     17.8%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;2.4 KiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;2.0 KiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;       17.9%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;     16.7%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;-118.7%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;60.0%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;          206&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;64×64    &lt;/td&gt;&lt;td align=&quot;right&quot;&gt; 2018&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;  7.0 MiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;  5.8 MiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;     17.8%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;3.6 KiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;2.9 KiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;       18.0%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;     15.8%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;-112.7%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;70.0%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;          279&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;128×128  &lt;/td&gt;&lt;td align=&quot;right&quot;&gt; 1411&lt;/td&gt;&lt;td align=&quot;right&quot;&gt; 11.2 MiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;  8.7 MiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;     22.0%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;8.1 KiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;6.3 KiB&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;       20.1%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;     17.5%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt; -89.7%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;61.0%&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;          209&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
  &lt;tfoot&gt;
    &lt;tr&gt;&lt;th&gt;TOTAL    &lt;/th&gt;&lt;th align=&quot;right&quot;&gt; 4973&lt;/th&gt;&lt;th align=&quot;right&quot;&gt; 21.9 MiB&lt;/th&gt;&lt;th align=&quot;right&quot;&gt; 17.5 MiB&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;     19.9%&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;4.5 KiB&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;3.6 KiB&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;       18.6%&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;     16.6%&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;-118.7%&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;70.0%&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;          694&lt;/th&gt;&lt;/tr&gt;
  &lt;/tfoot&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;&lt;small&gt;PNG images saved with libpng at &lt;code&gt;effort=4, compression=9&lt;/code&gt;, then optimized using &lt;code&gt;optipng -o2&lt;/code&gt;, JXL images encoded using &lt;code&gt;vips jxlsave lossless=1 effort=7 strip=1&lt;/code&gt; via VIPS/libjxl.&lt;/small&gt;&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;As the table shows, using lossless JXL images over size-optimized PNG images (using optipng’s default settings) provides a roughly 20% gain. This does not look like much, until you consider how often these files are downloaded: A 20% file size reduction may only save 1-2 MiB of disk space, but if they are downloaded over and over again by many clients, it will save a lot of bandwidth.&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;Interesting JXL encoding findings&lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;As a sidequest, I was curious why some images were larger than their PNG counterparts when encoded with JXL, and what the ones that were significantly smaller were.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;In short, the biggest size reductions for JXL existed on images that were already small as PNG, and contained large, flat color surfaces with hard edges and simple shapes. They were not very interesting, and much of JXL’s wins come from accumulating smaller gains across all files, which compound the bigger icons get (especially at 128x128px, where JXL truly shines).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;The events were JXL loses to PNG are more interesting: For example, it does quite poorly with pixel-art images that have a lot of repeating patterns. Those are encoded well by PNG, but less efficiently by JXL. Take for example Vonsh:&lt;/p&gt;



&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;a href=&quot;https://blog.tenstral.net/wp-content/uploads/2026/09/vonsh_vonsh.png&quot;&gt;&lt;img alt=&quot;&quot; class=&quot;wp-image-2137&quot; height=&quot;64&quot; src=&quot;https://blog.tenstral.net/wp-content/uploads/2026/09/vonsh_vonsh.png&quot; style=&quot;width: 151px; height: auto;&quot; width=&quot;64&quot; /&gt;&lt;/a&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;Icon of &lt;a href=&quot;https://github.com/aurb/vonsh/&quot;&gt;Vonsh&lt;/a&gt;, an SDL-based snake game, which PNG compresses better than JXL&lt;/figcaption&gt;&lt;/figure&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;My guess is that while PNG can exploit the repeating pixel patterns for compression, JXL’s predicts surrounding pixels from its neighbours, which fails too often and makes it pay almost full entropy per pixel. In this single rare case, the PNG is at 5.4 KiB, while the JXL is almost 8 KiB in size.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Other cases I looked at were arguably buggy input data, where color channels were hidden under the alpha channel of the input image. PNG could probably again exploit repeats, while we were forcing JXL to encode pixels that were invisible in the final image. This is arguably a problem with the original input data. Currently, AppStream does not make any changes to icons at all, but in future we might add a filter that removes invisible colors from images to solve this pathological case (it was only two icons out of 5000 though, so it is not a high priority).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;The third case I found where JXL loses to PNG were icons with checkerboard-like patterns:&lt;/p&gt;



&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;a href=&quot;https://blog.tenstral.net/wp-content/uploads/2026/09/x3270_x3270.png&quot;&gt;&lt;img alt=&quot;&quot; class=&quot;wp-image-2139&quot; height=&quot;64&quot; src=&quot;https://blog.tenstral.net/wp-content/uploads/2026/09/x3270_x3270.png&quot; style=&quot;width: 148px; height: auto;&quot; width=&quot;64&quot; /&gt;&lt;/a&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;Icon of &lt;a href=&quot;https://x3270.bgp.nu/&quot;&gt;x3270&lt;/a&gt;, an IBM 3270 Terminal Emulator&lt;/figcaption&gt;&lt;/figure&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;For those, PNG can likely again exploit the repeating patterns, while a checkerboard layout is pretty bad for left/top predictors like JXL’s. However, in this case the size difference (and loss for JXL) is only 450 bytes, so even though JXL loses to PNG, it does so not by much.&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;JXL in AppStream&lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Given these findings, JPEG-XL is the default image format starting with AppStream 1.2.0. AppStream Compose will encode all images losslessly as JXL, while screenshots are encoded in lossy mode at &lt;code&gt;Q=90 effort=7&lt;/code&gt;. Since the optipng step does not happen for JXL images, this comes at no speed penalty and is even a bit faster on modern x86_64 CPUs (where libjxl can use SIMD). PNG is still available, and Compose can be told to switch between the two formats.&lt;/p&gt;



&lt;h4 class=&quot;wp-block-heading&quot;&gt;Upsides of JXL in AppStream right now&lt;/h4&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;If you use JXL in Compose or the recent release of &lt;a href=&quot;https://github.com/ximion/appstream-generator&quot;&gt;appstream-generator&lt;/a&gt;, you will get much smaller images and, for screenshots, will benefit from other JPEG-XL features such as progressive decoding, providing a far nicer user experience. libAppStream has supported JXL icons since version 1.1.3, so your clients will need that version or a newer one, and all software centers will have to support loading JXL images (which all of them do, provided the right plugins are installed).&lt;/p&gt;



&lt;h4 class=&quot;wp-block-heading&quot;&gt;Downsides of switching to JXL too quickly&lt;/h4&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;JXL is a very new format, so web browsers might not yet display it if you are serving webpages. Your clients may also have bugs in processing JXL images, as the format is still “new”. For example, switching on JXL in Debian sent KDE Discover into an infinite loop on startup while trying to load the icons (an issue which &lt;a href=&quot;https://invent.kde.org/frameworks/kimageformats/-/commit/458257b7a32417c995d3a95a65b38586eee7a91a&quot;&gt;has been fixed&lt;/a&gt;, but clients will need that patch first before JXL is switched on).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;This currently makes JXL enablement only possible when you &lt;strong&gt;know&lt;/strong&gt; that your clients can support it. This is the case for me in Debian Unstable and Debian 14, which are using JXL images for a few weeks now, but not for any older releases. Platforms like Flatpak have it even harder, because they do know even less about their clients. So, even though it has big advantages, you may want to hold off on using JXL right away, and force PNG by setting the &lt;code&gt;ImageFormat&lt;/code&gt; key to &lt;code&gt;png&lt;/code&gt; in &lt;code&gt;appstream-generator&lt;/code&gt;‘s configuration, or passing &lt;code&gt;--image-format=png&lt;/code&gt; to &lt;code&gt;appstreamcli compose&lt;/code&gt;.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;It is also worth mentioning that JPEG-XL is much, much slower on systems that do not have SIMD instructions or for which the libjxl/jxl-rs library does not have them (such as apparently riscv64 right now). If this is a concern, you might not want to switch to JXL right away.&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;Media pipeline improvements &lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Besides the JXL default change, AppStream 1.2.0 also comes with a complete overhaul of its media processing pipeline. While &lt;code&gt;libappstream&lt;/code&gt;, AppStream’s main library, does not do any media processing and comes with very minimal dependencies to be embedded in client applications and used on servers, the same can not be said about &lt;code&gt;libappstream-compose&lt;/code&gt;, AppStream’s library to build metadata generating applications (the server-side part, usually).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;The &lt;code&gt;compose&lt;/code&gt; library has to render fonts into font specimen cards, inspect translation files, render SVG images, decode all kinds of raster images, inspect video files, etc. Especially the fonts, and the fact that fonts can appear in SVG images, has caused issues in the past, as &lt;code&gt;libappstream-compose&lt;/code&gt; is a heavily threaded library and most font libraries can only work from a single thread. This forced the library to essentially go into single-thread mode anytime anything that could touch a font was being processed.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;AppStream also originally was created for a “safe world” where applications were vetted by the distributors before their metadata was processed. This is increasingly not the case, so it made sense to put at least a few guardrails on the most complex part of the pipeline: The media processing. As part of the change, media processing was split out into a separate worker process. This solved two problems at once: Font handling was isolated in a single-threaded binary – if we wanted to handle fonts in parallel, we could simply spawn more workers. And, being in a separate process, the media processing could now be sandboxed.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;As part of the multiprocess changes, Compose also switched from using &lt;a href=&quot;https://gitlab.gnome.org/GNOME/gdk-pixbuf/&quot;&gt;GdkPixbuf&lt;/a&gt; to &lt;a href=&quot;https://github.com/libvips/libvips&quot;&gt;VIPS&lt;/a&gt; for image processing. The latter allows for much more fine-grained control over the image output and encoding, and comes with a lot of well-maintained filters and operations, which made it possible to eliminate a fair chunk of AppStream’s hand-rolled image processing operations. As part of this transition, we unfortunately lost the ability to read &lt;a href=&quot;https://en.wikipedia.org/wiki/X_PixMap&quot;&gt;XPM&lt;/a&gt; images, which dropped about 20-30 applications from the pool at Debian. But in the name of security, this is a sensible choice, especially since most XPM icons were very small and low-resolution, and applications using them could benefit from adding a high-quality PNG icon anyway. With VIPS, we also now restrict the amount of image formats we can load to a sensible set, so extremely niche or unexpected formats will be outright rejected (this includes sane-but-unusual formats for screenshots and icons, such as &lt;a href=&quot;https://de.wikipedia.org/wiki/Tagged_Image_File_Format&quot;&gt;TIFF&lt;/a&gt; images).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;The Compose library, with all of these changes, will now just request high-level operations (e.g. “render a font card for this font to a JXL image”) from the worker, and provide it with input data in sealed &lt;a href=&quot;https://man7.org/linux/man-pages/man2/memfd_create.2.html&quot;&gt;memfd&lt;/a&gt;s and output locations as FDs as well. On Linux systems, the worker will use &lt;a href=&quot;https://docs.kernel.org/userspace-api/landlock.html&quot;&gt;Landlock&lt;/a&gt; if available, to block all write access to the filesystem, deny device access and deny TCP and UDP as well. The sandbox can certainly be tightened a fair bit in future, but this was a good and safe start to gain some experience with it without having things break too easily, given the many places Compose is used in (also, Landlock’s API is surprisingly nice to use, so it was easier than I thought to add in this early version).&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;With all of these changes, the &lt;code&gt;libappstream-compose&lt;/code&gt; library is now also officially marked API-stable, so you should be able to rely on it in future to build new things (its API has barely changed in the past, and now with the new media API and defaults change in place, it was time to declare it stable).&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;I want to see / try this!&lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Currently, the easiest way to have a look at the new data is to check out Debian Unstable. If you have a JXL-enabled browser, you can also see the icons in &lt;a href=&quot;https://appstream.debian.org/sid/&quot;&gt;AppStream Generator’s HTML pages for Debian Sid&lt;/a&gt;. If you are using appstream-generator for your distribution, you will also get much more pleasant statistics and HTML pages, as well as fully deterministic media output and a whole bunch of security updates, so, update to its recent 1.0 release.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Please keep in mind that if you switch to JXL, the client tools receiving the image data have to support it. Support varies depending on the Linux distribution, so, test it first and switch the default back to PNG in case you encounter any issues.&lt;/p&gt;



&lt;h3 class=&quot;wp-block-heading&quot;&gt;What’s next?&lt;/h3&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;With so many features and changes landed, the next changes in AppStream will focus on improving what already exists and fixing any issues (there will be more blogposts about the other features 1.2.x delivers!). Testing with the entire Debian archive as data source makes me fairly confident though that there will not be many problems. In the longer term, tightening the media processing sandbox will also be something we might want to do, e.g. by hiding parts of the filesystem tree or filtering syscalls.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;For JPEG-XL, one obvious question is “Will you add support for it to the Freedesktop icon-theme specification as supported format alongside PNG, SVG(Z), and XPM?”. For on-disk icon repositories, JXL’s space-savings are less compelling, and it being HDR-capable is also not necessarily a killer feature (PNG can go a long way!). However, JPEG-XL’s ability to immediately decode larger images at reduced resolution without resampling could legitimately be very powerful here, as applications could ship a single large image and quickly decode it at 1/2, 1/4 or 1/8 the size for different purposes in their UI. JPEG-XL also supports spot-color extra channels, which applications could use as masks to recolor raster icons at render time. This could be incredibly nice to color symbolic icons on-the-fly without any SVG and CSS. JXL also provides richer metadata, which might be neat for (license/author) documentation. So, the answer here is: Maybe it makes sense to allow another format, but this will have to be discussed first, as it would force JXL into every toolkit and desktop, which is a much bigger ask than supporting it only in AppStream.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;As always, let me know what you think and please report any issues or bugs directly against &lt;a href=&quot;https://github.com/ximion/appstream&quot;&gt;AppStream&lt;/a&gt; or &lt;a href=&quot;https://github.com/ximion/appstream-generator&quot;&gt;AppStream Generator&lt;/a&gt; if you encounter problems that are with the tools, and not with a project’s metadata.&lt;/p&gt; </description> 
	<pubDate>Thu, 10 Sep 2026 17:48:00 +0000</pubDate>

</item> 
<item>
	<title>Ben Hutchings: FOSS activity in August 2026</title>
	<guid>https://www.decadent.org.uk/ben/blog/2026/09/10/foss-activity-in-august-2026</guid>
	<link>https://www.decadent.org.uk/ben/blog/2026/09/10/foss-activity-in-august-2026.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/benh.png&quot; width=&quot;109&quot; height=&quot;100&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Thereâ€™s not a whole lot to report here.  During August I spent some
time on holiday and also had less work time available for Debian LTS.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Debian packages:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/firmware-nonfree&quot;&gt;firmware-nonfree&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/src:firmware-nonfree&quot;&gt;Bugs&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;replied to &lt;a href=&quot;https://bugs.debian.org/1143446&quot;&gt;#1143446: firmware-nonfree: split Lontium firmware into a separate binary package&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://salsa.debian.org/kernel-team/firmware-nonfree/-/merge_requests/152&quot;&gt;!152: lontium: create new package containing firmware for Lontium display bridge devices&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;opened and merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/firmware-nonfree/-/merge_requests/153&quot;&gt;!153: Update to 20260810&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/firmware-nonfree/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 20260810-1 to unstable&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux&quot;&gt;linux&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/src:linux&quot;&gt;Bugs&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;replied to &lt;a href=&quot;https://bugs.debian.org/1141407&quot;&gt;#1141407: linux-image-amd64: hid-generic 0003:051D:0002.0002: Event data for report 22 was too short (4 vs 2)&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://bugs.debian.org/1143619&quot;&gt;#1143619: linux-image-686: metapackage missing for 6.1.180-1 on 686&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;closed &lt;a href=&quot;https://bugs.debian.org/1144056&quot;&gt;#1144056: linux-image-amd64: missing CONFIG_CRYPTO_SHA384 causes IMA error&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2039&quot;&gt;!2039: Add support for Alcor Micro AU6625 PCI-E Flash card reader&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2041&quot;&gt;!2041: Update to 5.10.262&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2042&quot;&gt;!2042: 6.1 stable updates&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2048&quot;&gt;!2048: Update to 6.1.180&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2050&quot;&gt;!2050: 6.1 stable updates&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;reviewed &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2059&quot;&gt;!2059: [arm64] Enable CONFIG_SND_SOC_ES8328_I2C as module&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;reviewed and merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2063&quot;&gt;!2063: 6.1 stable updates&lt;/a&gt; (LTS)&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux/-/merge_requests/2068&quot;&gt;!2068: 6.1 stable updates&lt;/a&gt; (LTS)&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 6.1.180-1 to bookworm-security (LTS)&lt;/li&gt;
              &lt;li&gt;uploaded version 7.1.7-1~bpo13+1 to trixie-backports&lt;/li&gt;
              &lt;li&gt;uploaded version 7.1.8-1~bpo13+1 to trixie-backports&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-6.12&quot;&gt;linux-6.12&lt;/a&gt; (LTS):
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-6.12/news/&quot;&gt;Uploads&lt;/a&gt;:
            &lt;ul&gt;
              &lt;li&gt;uploaded version 6.12.100-1~deb12u1 to bookworm-security&lt;/li&gt;
              &lt;li&gt;uploaded version 6.12.101-1~deb12u1 to bookworm-security&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/linux-base&quot;&gt;linux-base&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;Merge requests:
            &lt;ul&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux-base/-/merge_requests/22&quot;&gt;!22: Also copy config file to /boot&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;merged &lt;a href=&quot;https://salsa.debian.org/kernel-team/linux-base/-/merge_requests/23&quot;&gt;!23: New hooks ignore all calls by unpackaged kernels&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Mailing lists:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://lists.debian.org/debian-kernel/&quot;&gt;debian-kernel&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/b844e73d47b44cbf08be2664e26fc2393038346a.camel@decadent.org.uk&quot;&gt;Agenda items for kernel-team meeting on 2026-08-19&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/83730f8bd7aac43fb90af084984a84c35a177e57.camel@decadent.org.uk&quot;&gt;Opaque tables of numbers in r8169 driver&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://lists.debian.org/debian-lts-announce/&quot;&gt;debian-lts-announce&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/anNgZasHL66gqrCC@decadent.org.uk&quot;&gt;[SECURITY] [DLA 4720-1] linux security update&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/anWlW0WUJpgxfCMc@decadent.org.uk&quot;&gt;[SECURITY] [DLA 4724-1] linux-6.12 new package&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lists.debian.org/aoQ5HmDwwEXKCs73@decadent.org.uk&quot;&gt;[SECURITY] [DLA 4745-1] linux-6.12 security update&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://lore.kernel.org/linux-input/&quot;&gt;linux-input&lt;/a&gt;:
        &lt;ul&gt;
          &lt;li&gt;posted &lt;a href=&quot;https://lore.kernel.org/linux-input/aoF-jIn9gk9kJ7Pz@decadent.org.uk/T/&quot;&gt;[PATCH] HID: core: demote warning to debug level&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt; </description> 
	<pubDate>Thu, 10 Sep 2026 13:57:48 +0000</pubDate>

</item> 
<item>
	<title>Russ Allbery: podlators v6.1.1</title>
	<guid>https://www.eyrie.org/~eagle/journal/2026-09/001.html</guid>
	<link>https://www.eyrie.org/~eagle/journal/2026-09/001.html</link>
     <description>  &lt;p&gt;
podlators is the package containing Pod::Man, Pod::Text, and other
tools for converting POD documentation into manual pages and simple
text documents.
&lt;/p&gt;

&lt;p&gt;
This release fixes a long-standing bug in Pod::Text and subclasses
where a pathological level of indentation could cause the wrapping
code to go into an infinite loop. Thanks to Jitka Plesnikova for
the report. This was assigned CVE-2026-82560, although I make no
guarantees that podlators is safe to run on untrusted input and
therefore not fully treating this like a security issue.
&lt;/p&gt;

&lt;p&gt;
While fixing that bug, I noticed a bug in Pod::Text::Overstrike&#39;s
wrapping code that would leave stray formatting at the start of the
next line in some situations. That is also fixed in this release.
&lt;/p&gt;

&lt;p&gt;
You can get the current podlators release from CPAN or from the
&lt;a href=&quot;https://www.eyrie.org/~eagle/software/podlators/&quot;&gt;podlators distribution page&lt;/a&gt;.
&lt;/p&gt; </description> 
	<pubDate>Thu, 10 Sep 2026 02:28:00 +0000</pubDate>

</item> 
<item>
	<title>Thorsten Alteholz: My Debian Activities in August 2026</title>
	<guid>http://blog.alteholz.eu/?p=2849</guid>
	<link>http://blog.alteholz.eu/2026/09/my-debian-activities-in-august-2026/</link>
     <description>  &lt;h3&gt;&lt;strong&gt;Debian LTS/ELTS&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;&lt;/p&gt;&lt;p&gt;This was my hundred-forty-sixth month that I did some work for the Debian LTS initiative, started by Raphael Hertzog at Freexian.
&lt;/p&gt;
&lt;p&gt;
Unfortunately the number of distributed working hours had been rather low this month, so the list contains much less entries than normal. During my allocated time I uploaded or worked on:  
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;[&lt;a href=&quot;https://lists.debian.org/debian-lts-announce/2026/08/msg00004.html&quot;&gt;DLA 4713-1&lt;/a&gt;]  sslh security update to fix one CVE in Bookworm related to a so-called “link following”
vulnerability.&lt;/li&gt;&lt;li&gt;[&lt;a href=&quot;https://lists.debian.org/debian-lts-announce/2026/08/msg00003.html&quot;&gt;DLA 4714-1&lt;/a&gt;] libmodbus security update to fix one CVEs in Bookworm related to a stack-based Buffer Overflow vulnerability. 
&lt;/li&gt;&lt;li&gt;[&lt;a href=&quot;https://lists.debian.org/debian-lts-announce/2026/07/msg00031.html&quot;&gt;DLA 4715-1&lt;/a&gt;]  kissfft security update to fix two CVEs in Bookworm related to integer overflows.
&lt;/li&gt;&lt;/ul&gt;



&lt;p&gt;
Last but not least I spent days with FD work at the beginning of the month. The last remaining hours I continued to work on &lt;i&gt;cups&lt;/i&gt; and &lt;i&gt;hplip&lt;/i&gt;. Unfortunately this work did not result in an upload yet.
&lt;/p&gt;



&lt;h3&gt;&lt;strong&gt;Debian Printing&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;This month I did not upload any package but just worked on some bugs.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;This work is generously funded by &lt;a href=&quot;https://www.freexian.com&quot;&gt;Freexian&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;



&lt;h3&gt;&lt;strong&gt;Debian Lomiri&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;This month I worked on new Lomiri Apps. Due to a broken disk, the progress was not as expected. But stay tuned!&lt;/p&gt;



&lt;p&gt;Not really related to Lomiri, but to Debian EDU, I fixed an incus related bug in &lt;i&gt;sitesummary&lt;/i&gt;.
&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;This work is generously funded by &lt;a href=&quot;https://freiesoftware.gmbh/&quot;&gt;Fre(i)e Software GmbH&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;



&lt;h3&gt;&lt;strong&gt;Debian Astro&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;This month I uploaded a new upstream version  or a bugfix version of:&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/einsteinpy&quot;&gt;einsteinpy&lt;/a&gt; to unstable, fixing a dependency bug.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/supernovas&quot;&gt;supernovas&lt;/a&gt; to unstable, sponsored upload of a new upstream version.&lt;/li&gt;&lt;/ul&gt;



&lt;h3&gt;&lt;strong&gt;Debian IoT&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;Unfortunately I had no time to work in this category this month.&lt;/p&gt;



&lt;h3&gt;&lt;strong&gt;Debian Mobcom&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;This month I uploaded a new upstream version  or a bugfix version of:&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/libosmocore&quot;&gt;libosmocore&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmocom-analog&quot;&gt;osmocom-analog&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/libosmo-netif&quot;&gt;libosmo-netif&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-trx&quot;&gt;osmo-trx&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/libosmo-abis&quot;&gt;libosmo-abis&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/libosmo-sigtran&quot;&gt;libosmo-sigtran&lt;/a&gt; to experimental.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-mgw&quot;&gt;osmo-mgw&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-bsc&quot;&gt;osmo-bsc&lt;/a&gt; to experimental.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-sgsn&quot;&gt;osmo-sgsn&lt;/a&gt; to experimental.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-pcu&quot;&gt;osmo-pcu&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-hlr&quot;&gt;osmo-hlr&lt;/a&gt; to unstable.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/osmo-tetra&quot;&gt;osmo-tetra&lt;/a&gt; to unstable.&lt;/li&gt;&lt;/ul&gt;



&lt;h3&gt;&lt;strong&gt;misc&lt;/strong&gt;&lt;/h3&gt;



&lt;p&gt;This month I uploaded a new upstream version  or a bugfix version of:&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/tango&quot;&gt;tango&lt;/a&gt; to unstable to fix bugs and do a soname transition.&lt;/li&gt;&lt;li&gt;… &lt;a href=&quot;https://tracker.debian.org/pytango&quot;&gt;pytango&lt;/a&gt; to unstable to fix bugs and do a soname transition.&lt;/li&gt;&lt;/ul&gt; </description> 
	<pubDate>Wed, 09 Sep 2026 15:49:32 +0000</pubDate>

</item> 
<item>
	<title>Enrico Zini: Financial risks in 2026</title>
	<guid>https://www.ezini.eu/blog/2026/financial-risks-in-2026</guid>
	<link>https://www.ezini.eu/blog/2026/financial-risks-in-2026</link>
     <description>  &lt;p&gt;I asked the banker who is my reference at the bank something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Give that we are talking about the consequences of the tantrum of a fascist
foreign government, what happened to them (who are also people close and dear
to me), in some future can very well happen to me.&lt;/p&gt;
&lt;p&gt;Suddenly my risk profile shot up under the roof.&lt;/p&gt;
&lt;p&gt;What do you suggest me to do? Should I find a trusted source of gold bullions
to bury under the cellar at home?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The answer was something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sadly YES, given that the USA have a sort of financial monopoly they can
entitle themselves to arbitrarily define a person/organization as a terrorist
without any trial or judicial course, and as a consequence apply sanctions
that cannot be effectively counteracted, not even abroad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I didn&#39;t have this in my 2026 bingo card, but here we are.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;For more details, see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;https://www.inventati.org/campaign/press&quot;&gt;A/I press release&lt;/a&gt; under &quot;12. Banca Etica: the sanction also affected an Italian bank account&quot;&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;https://www.bancaetica.it/area-stampa/autistici-inventati-banca-etica-condanna-uso-improprio-ofac-valutazioni-per-non-chiudere-il-conto/&quot;&gt;public statement from the bank&lt;/a&gt; (in Italian)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For some broader context on this kind of actions from the USA, see also:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Francesca_Albanese#Sanctions_by_the_United_States&quot;&gt;The same sactions against UN Special Rapporteur Francesca Albanese&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Executive_Order_14203&quot;&gt;Executive Order 14203 titled &quot;Imposing Sanctions on the International Criminal Court&quot;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt; </description> 
	<pubDate>Tue, 08 Sep 2026 07:05:22 +0000</pubDate>

</item> 
<item>
	<title>Bits from Debian: New Debian Developers and Maintainers (July and August 2026)</title>
	<guid>tag:bits.debian.org,2026-09-07:/2026/09/new-developers-2026-09.html</guid>
	<link>https://bits.debian.org/2026/09/new-developers-2026-09.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/dwn.png&quot; width=&quot;77&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;The following contributor got their Debian Developer account in the last two
months:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nicolas Peugnet (nicolasp)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following contributors were added as Debian Maintainers in the last two
months:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Antoine Lassagne&lt;/li&gt;
&lt;li&gt;Ivan Hu&lt;/li&gt;
&lt;li&gt;Jesse Rhodes&lt;/li&gt;
&lt;li&gt;Haolin Xue&lt;/li&gt;
&lt;li&gt;Léo Haf&lt;/li&gt;
&lt;li&gt;Rony João de Sousa&lt;/li&gt;
&lt;li&gt;Luke Yasuda&lt;/li&gt;
&lt;li&gt;Darshaka Pathirana&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Congratulations!&lt;/p&gt; </description> 
	<pubDate>Mon, 07 Sep 2026 21:00:00 +0000</pubDate>

</item> 
<item>
	<title>Colin Watson: Free software activity in August 2026</title>
	<guid>tag:www.chiark.greenend.org.uk,2026-09-07:/~cjwatson/blog/activity-2026-08.html</guid>
	<link>https://www.chiark.greenend.org.uk/~cjwatson/blog/activity-2026-08.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/cjwatson.png&quot; width=&quot;70&quot; height=&quot;82&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;My Debian contributions this month were all &lt;a href=&quot;https://www.freexian.com/about/debian-contributions/&quot;&gt;sponsored&lt;/a&gt; by Freexian.&lt;/p&gt;
&lt;p&gt;You can also support my work directly via &lt;a href=&quot;https://liberapay.com/cjwatson&quot;&gt;Liberapay&lt;/a&gt; or &lt;a href=&quot;https://github.com/sponsors/cjwatson&quot;&gt;GitHub Sponsors&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Personal note&lt;/h2&gt;
&lt;p&gt;This month, my Dad unexpectedly passed away after a short illness.  As a result I obviously got less work done than usual, and I still have a lot to take care of (since I’m the executor of his will, as well as helping with funeral arrangements) while grieving and generally having less focus and energy.  Having routine work to do is one of the ways I cope with this sort of thing, but all the same, I hope people will bear with me and maybe remind me if I seem to be dropping the ball on something you especially need.&lt;/p&gt;
&lt;h2&gt;&lt;span class=&quot;caps&quot;&gt;LLM&lt;/span&gt; vote&lt;/h2&gt;
&lt;p&gt;[Content note: strong opinions.]&lt;/p&gt;
&lt;p&gt;I voted in &lt;a href=&quot;https://www.debian.org/vote/2026/vote_002&quot;&gt;General Resolution: &lt;span class=&quot;caps&quot;&gt;LLM&lt;/span&gt; usage in Debian&lt;/a&gt;.  My vote was pretty much the opposite of what ended up winning, so I’m quite disappointed.  My personal opinion is that LLMs are &lt;a href=&quot;https://softwarecrisis.dev/letters/llmentalist/&quot;&gt;cognitive hazards to their users&lt;/a&gt; that impose ecological costs far out of proportion to their utility at a time when &lt;a href=&quot;https://wmo.int/publication-series/state-of-global-climate/state-of-global-climate-2025&quot;&gt;the world absolutely cannot afford them&lt;/a&gt;.  When the impossible economics of the large commercial models are finally allowed to catch up with reality, I expect there to be &lt;a href=&quot;https://www.wheresyoured.at/what-happens-if-openai-dies/&quot;&gt;significant macroeconomic consequences&lt;/a&gt;, and that people who have become dependent on them will have problems; and who knows what the copyright situation on their output really is.  I’m not convinced that &lt;a href=&quot;https://blog.glyph.im/2026/09/but-what-about-video-games.html&quot;&gt;local models&lt;/a&gt; are better enough on these axes to be worth the costs.&lt;/p&gt;
&lt;p&gt;Debian’s direct contribution to all that will be negligible on a global scale, and even the most radical proposals in the &lt;span class=&quot;caps&quot;&gt;GR&lt;/span&gt; didn’t expect that we could do much about upstreams that have gone all-in on LLMs.  Even so, I’d hoped that my fellow developers might be more willing to lean on our position in the free software ecosystem to make at least a moderately radical statement.  Instead, we’ve at best presented an undistinguished fence-sitting position to the world, and further entrenched the idea that humans can reliably do a good job of reviewing the output of tools that are designed to produce output plausible to humans.  I certainly don’t trust my own code review skills that far.&lt;/p&gt;
&lt;p&gt;Since I’ve never voluntarily used an &lt;span class=&quot;caps&quot;&gt;LLM&lt;/span&gt; (not counting LLMs being foisted on me by things like search results, support chatbots, or incoming pull requests, regardless of whether I asked for them), and don’t intend to for the foreseeable future, I doubt this will change much for me in terms of the way I work.  The winning option is a very weak one that imposes no new requirements on developers, which means that it also does nothing to stop me continuing to reject &lt;span class=&quot;caps&quot;&gt;LLM&lt;/span&gt;-generated material from Debian bug reports and merge requests in my areas of responsibility.  I know this probably won’t do much to satisfy people who have decided that Debian is slop now, but it’s the best I can do.&lt;/p&gt;
&lt;h2&gt;OpenSSH&lt;/h2&gt;
&lt;p&gt;I finally landed the &lt;a href=&quot;https://www.chiark.greenend.org.uk/~cjwatson/blog/openssh-gssapi-split.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;GSS&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; key exchange package split&lt;/a&gt; in our OpenSSH packaging.  Here’s the &lt;code&gt;NEWS&lt;/code&gt; entry:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;openssh&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m m-Double&quot;&gt;10.4&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unstable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;urgency&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;medium&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;openssh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;openssh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;longer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;GSS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;API&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;authentication&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exchange&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;support&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;adds&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pre&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;authentication&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attack&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;surface&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;generally&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;increases&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;should&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;only&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;be&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;used&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;specifically&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;needed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Users&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;who&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;need&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;these&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;features&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;should&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;install&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;openssh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gssapi&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;openssh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gssapi&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;instead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Colin&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Watson&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cjwatson&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;debian&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Sun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Aug&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2026&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;39&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I &lt;a href=&quot;https://salsa.debian.org/ssh-team/openssh/-/commit/4fec688eb614ba9ba758e66efa361285722dbdf8&quot;&gt;fixed a flaky autopkgtest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I upgraded from 10.4p1 to 10.5p1, which was a good test of keeping &lt;code&gt;openssh&lt;/code&gt; and the new &lt;code&gt;openssh-gssapi&lt;/code&gt; source package in sync.&lt;/p&gt;
&lt;h2&gt;PuTTY&lt;/h2&gt;
&lt;p&gt;I upgraded from 0.84 to 0.85.&lt;/p&gt;
&lt;h2&gt;Python packaging&lt;/h2&gt;
&lt;p&gt;New upstream versions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;anorack&lt;/li&gt;
&lt;li&gt;djangorestframework (fixing a &lt;a href=&quot;https://bugs.debian.org/1143299&quot;&gt;build failure&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;isort&lt;/li&gt;
&lt;li&gt;lazr.delegates (&lt;a href=&quot;https://bugs.debian.org/1083458&quot;&gt;dropping pkg_resources&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;lazr.restfulclient (&lt;a href=&quot;https://bugs.debian.org/1083460&quot;&gt;dropping pkg_resources&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;lazr.uri (&lt;a href=&quot;https://bugs.debian.org/1083461&quot;&gt;dropping pkg_resources&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;nbclient (fixing a &lt;a href=&quot;https://bugs.debian.org/1138816&quot;&gt;build failure&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;pydantic-settings&lt;/li&gt;
&lt;li&gt;python-argcomplete&lt;/li&gt;
&lt;li&gt;python-blockbuster&lt;/li&gt;
&lt;li&gt;python-makefun (fixing a &lt;a href=&quot;https://bugs.debian.org/1143367&quot;&gt;build failure&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;python-persistent&lt;/li&gt;
&lt;li&gt;python-pytest-run-parallel&lt;/li&gt;
&lt;li&gt;python-time-machine&lt;/li&gt;
&lt;li&gt;python-typing-inspection&lt;/li&gt;
&lt;li&gt;wcwidth&lt;/li&gt;
&lt;li&gt;zope.hookable&lt;/li&gt;
&lt;li&gt;zope.i18nmessageid&lt;/li&gt;
&lt;li&gt;zope.interface&lt;/li&gt;
&lt;li&gt;zope.proxy&lt;/li&gt;
&lt;li&gt;zope.security&lt;/li&gt;
&lt;li&gt;zope.testrunner&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The version treadmill continues: we’ve just finished dropping Python 3.13 as a supported version, so now we’ve started working on enabling Python 3.15 as a supported version.  Maximiliano Curia has been &lt;a href=&quot;https://lists.debian.org/debian-python/2026/08/msg00065.html&quot;&gt;very helpfully driving this&lt;/a&gt;.  I didn’t get as much done here as I’d have liked (see the top of this post), but I fixed a couple of packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1145192&quot;&gt;pydantic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1145112&quot;&gt;python-typing-extensions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other build/test failures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143283&quot;&gt;anorack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143285&quot;&gt;buildbot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1144623&quot;&gt;codespell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1144042&quot;&gt;django-prometheus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143359&quot;&gt;pendulum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143691&quot;&gt;pydantic-core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143365&quot;&gt;python-argcomplete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1145426&quot;&gt;python-ast-serialize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143364&quot;&gt;python-bcrypt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143366&quot;&gt;python-cross-web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1146106&quot;&gt;python-datamodel-code-generator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://salsa.debian.org/python-team/packages/python-djangorestframework-flex-fields/-/commit/42cba56dd872332a1b713b914be0f15bd97e7d43&quot;&gt;python-djangorestframework-flex-fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143369&quot;&gt;python-openapi-core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143469&quot;&gt;python-treq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143418&quot;&gt;scikit-build-core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I fixed some other bugs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1143722&quot;&gt;python-librosa: Hardcoded Python 3.13 in rules file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/1045218&quot;&gt;python-makefun: Fails to build source after successful build&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;bugs.debian.org&lt;/h2&gt;
&lt;p&gt;I deployed the fix for &lt;a href=&quot;https://bugs.debian.org/979319&quot;&gt;Invalid link rel=”canonical” on bugs.debian.org&lt;/a&gt;.  In the process I found a few bugs in recent undeployed code and &lt;a href=&quot;https://salsa.debian.org/debbugs-team/debbugs/-/compare/66628595f23bd079a748ad549dd986cd51dc498e...ecc8def8320b0f5297a2e31f9b3a051d164f5d59&quot;&gt;fixed them&lt;/a&gt;.&lt;/p&gt; </description> 
	<pubDate>Mon, 07 Sep 2026 19:25:04 +0000</pubDate>

</item> 
<item>
	<title>Vincent Bernat: Sidenotes with CSS anchor positioning</title>
	<guid>http://www.luffy.cx/en/blog/2026-css-sidenotes.html</guid>
	<link>https://vincent.bernat.ch/en/blog/2026-css-sidenotes</link>
     <description>  &lt;p&gt;I am a heavy user of sidenotes:&lt;sup id=&quot;fnref:phd&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:phd&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; they keep optional content next to the
text instead of sending the reader to the bottom of the page and back. &lt;a href=&quot;https://edwardtufte.github.io/tufte-css/&quot; title=&quot;Tufte CSS&quot;&gt;Tufte
CSS&lt;/a&gt; renders them without JavaScript but only accepts inline content. &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning&quot; title=&quot;CSS anchor positioning&quot;&gt;CSS
anchor positioning&lt;/a&gt;, now supported by recent browsers,&lt;sup id=&quot;fnref:anchor-support&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:anchor-support&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; is an
elegant alternative. Sidenotes can hold several blocks, still without
JavaScript, and fall back below the paragraph referencing them on narrow
viewports and older browsers.&lt;/p&gt;
&lt;p&gt;Inâ€¯2023, Eric Meyer demonstrated this technique in â€œ&lt;a href=&quot;https://meyerweb.com/eric/thoughts/2023/09/12/nuclear-anchored-sidenotes/&quot; title=&quot;Nuclear Anchored Sidenotes&quot;&gt;Nuclear Anchored
Sidenotes&lt;/a&gt;.â€� The main improvement over other solutions is that the notes can
sit anywhere in the HTML document. You can place them after the paragraph
referencing them, as regular block elements for text browsers, screen readers,
feed readers, and reader mode to render them properly:&lt;/p&gt;
&lt;figure class=&quot;lf-fullbleed&quot;&gt;&lt;div class=&quot;lf-media-outer&quot; style=&quot;width: 465px;&quot;&gt;&lt;span class=&quot;lf-media-inner&quot;&gt;&lt;img alt=&quot;Sidenotes rendered in Lynx appear after the paragraph they are called from.&quot; class=&quot;lf-media&quot; height=&quot;600&quot; src=&quot;https://d2pzklc15kok91.cloudfront.net/images/css-sidenotes/lynx@1x.62cb4bfb14577a.png&quot; width=&quot;465&quot; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;figcaption&gt;Rendering in Lynx, a text browser&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;When the viewport is too narrow or the browser does not support CSS anchor
positioning, you can style them so the reader can skip them or glance at them
without losing their position in the text:&lt;/p&gt;
&lt;figure class=&quot;lf-fullbleed&quot;&gt;&lt;div class=&quot;lf-media-outer&quot; style=&quot;width: 375px;&quot;&gt;&lt;span class=&quot;lf-media-inner&quot;&gt;&lt;img alt=&quot;Sidenotes rendered on a narrow viewport appear with a distinctive typography after the paragraph they are called from.&quot; class=&quot;lf-media lf-opaque&quot; height=&quot;667&quot; src=&quot;https://d2pzklc15kok91.cloudfront.net/images/css-sidenotes/narrow@1x.9afbc67e0bd4e9.png&quot; width=&quot;375&quot; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;figcaption&gt;Rendering below the paragraph on a narrow viewport&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Once the viewport is large enough, they appear in the margin, at the same
vertical position as the matching reference mark, unless they would collide with
a previous sidenote, as in the example below:&lt;sup id=&quot;fnref:runt&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:runt&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;figure class=&quot;lf-fullbleed&quot;&gt;&lt;div class=&quot;lf-media-outer&quot; style=&quot;width: 1427px;&quot;&gt;&lt;span class=&quot;lf-media-inner&quot;&gt;&lt;img alt=&quot;Sidenotes rendered on a large viewport appear in the margin. There are two of them. The first one is vertically aligned with the matching reference mark, while the second is rendered below as it would collide with the first otherwise.&quot; class=&quot;lf-media lf-opaque&quot; height=&quot;570&quot; src=&quot;https://d2pzklc15kok91.cloudfront.net/images/css-sidenotes/large@1x.b9822706e29afa.png&quot; width=&quot;1427&quot; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;figcaption&gt;Rendering in the margin on a large viewport&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;The gist of CSS anchoring is to position an element relative to another
elementâ€”the anchor. For the sidenotes, the anchor is the reference mark. I use
the following markup, with a data attribute to specify the anchor name:&lt;/p&gt;
&lt;div class=&quot;language-html codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fnref:YYY&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--lf-sn-YYY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#sidenote-YYY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;1&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The matching note is an &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt; element carrying the same data attribute for
the anchor name. We put it after the paragraph holding the reference mark:&lt;/p&gt;
&lt;div class=&quot;language-html codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;aside&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;note&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sidenote-YYY&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--lf-sn-YYY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;1&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;A first paragraph.&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;A second paragraph.&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;aside&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On a narrow viewport or when the browser is too old for CSS anchoring, we style
the sidenote, which stays below its paragraph, with a muted color:&lt;/p&gt;
&lt;div class=&quot;language-css codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;aside&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;note&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;margin-block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;rlh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On a wide viewport and when the browser is recent enough, we move the sidenote
to the right margin:&lt;/p&gt;
&lt;div class=&quot;language-css codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;supports&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;anchor-name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;custom-ident&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;)))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;72rem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;anchor-name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom-ident&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;/* â†’ anchor-name: --lf-sn-YYY */&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;aside&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;note&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;anchor-name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;--lf-sidenote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;position-anchor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data-anchor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom-ident&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;/* â†’ position-anchor: --lf-sn-YYY */&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;anchor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;anchor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;--lf-sidenote&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;rlh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;rlh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;inherit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;attr()&lt;/code&gt; extracts the anchor name for the reference mark from the &lt;code&gt;data-anchor&lt;/code&gt;
attribute. It returns a string, unless we specify a CSS unit or a type, like
here: the browser parses the data attribute as a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/custom-ident&quot; title=&quot;&amp;lt;custom-ident&amp;gt; on MDN&quot;&gt;custom
identifier&lt;/a&gt;, which &lt;code&gt;anchor-name&lt;/code&gt; validates as a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/dashed-ident&quot; title=&quot;&amp;lt;dashed-ident&amp;gt; on MDN&quot;&gt;dashed
identifier&lt;/a&gt;, a custom identifier starting with two
dashes.&lt;sup id=&quot;fnref:attr-support&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:attr-support&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The note itself is absolutely positioned past the right edge of the main block.
It selects the matching reference mark as its anchor with &lt;code&gt;position-anchor&lt;/code&gt; set
to the value of the &lt;code&gt;data-anchor&lt;/code&gt; attribute. Each note is also an anchor named
&lt;code&gt;--lf-sidenote&lt;/code&gt;. We use it to keep the next note from colliding with this one.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/anchor&quot; title=&quot;anchor() CSS function on MDN&quot;&gt;&lt;code&gt;anchor()&lt;/code&gt; CSS function&lt;/a&gt; lets us position the noteâ€™s top
edge relative to its anchor: &lt;code&gt;anchor(top)&lt;/code&gt; aligns the top edge of the note with
the top edge of the reference mark. It can also take another anchor as a
parameter: &lt;code&gt;anchor(--lf-sidenote bottom)&lt;/code&gt; would align the top edge of the note
with the bottom edge of the closest preceding anchor named &lt;code&gt;--lf-sidenote&lt;/code&gt;â€”so
the previous note.&lt;sup id=&quot;fnref:reference&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;https://vincent.bernat.ch#fn:reference&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; Like &lt;code&gt;attr()&lt;/code&gt;, &lt;code&gt;anchor()&lt;/code&gt; accepts a fallback
value as its second parameter and use it when the named anchor does not exist.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;top&lt;/code&gt; property handles three cases, illustrated in the following diagram:&lt;/p&gt;
&lt;figure class=&quot;lf-fullbleed&quot;&gt;&lt;div class=&quot;lf-media-outer&quot; style=&quot;width: 913px;&quot;&gt;&lt;span class=&quot;lf-media-inner&quot;&gt;&lt;img alt=&quot;Diagram of three sidenotes anchored to their reference marks. The first one is aligned with the top of its own reference mark, as no note comes before it. The second one would overlap the first, so it takes the bottom of the first note as anchor and sits one line below it. The third one comes far enough down the page to align with its own reference mark again.&quot; class=&quot;lf-media&quot; height=&quot;660&quot; src=&quot;https://d2pzklc15kok91.cloudfront.net/images/css-sidenotes/anchors.7ed3294df30cae.svg&quot; width=&quot;913&quot; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;figcaption&gt;The three cases for the vertical position of a note&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ol&gt;
&lt;li&gt;The first noteâ€™s top edge aligns with the top edge of its reference mark: as
   there is no previous note, &lt;code&gt;anchor(--lf-sidenote bottom, -1rlh) + 1rlh&lt;/code&gt;
   resolves to 0 and &lt;code&gt;max()&lt;/code&gt; returns &lt;code&gt;anchor(top)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When the reference mark of a later note sits above the bottom of the previous
   note, plus some vertical space, the note goes below the previous one to avoid
   a collision. &lt;code&gt;max()&lt;/code&gt; returns &lt;code&gt;anchor(--lf-sidenote bottom) + 1rlh&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Otherwise, the noteâ€™s top edge aligns with the reference markâ€™s top edge, as
   &lt;code&gt;max()&lt;/code&gt; returns &lt;code&gt;anchor(top)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;Have a look at the &lt;a href=&quot;https://github.com/vincentbernat/vincent.bernat.ch/blob/main/content/media/css/luffy1.sidenotes.css&quot; title=&quot;Stylesheet for the sidenotes of this blog&quot;&gt;complete stylesheet&lt;/a&gt;, which also adapts the
reference mark to the location of the note: a â€œâ†“â€� arrow when the note sits below
the paragraph, a â€œâ†’â€� arrow when it moves to the margin. Gwernâ€™s â€œ&lt;a href=&quot;https://gwern.net/sidenote&quot; title=&quot;Sidenotes In Web Design&quot;&gt;Sidenotes In
Web Design&lt;/a&gt;â€� lists more implementations and their trade-offs.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://danluu.com/bug-blind/&quot; title=&quot;Bug blindness&quot;&gt;Some bloggers&lt;/a&gt; aim to write a post in 30 minutes. I planned to publish
three web-related articles this weekend. Instead, I spent an inordinate amount
of time elsewhere: about 15 commits on the build system, a pull request to
&lt;a href=&quot;https://github.com/pygments/pygments/pull/3294&quot; title=&quot;CSS: support nested rule&quot;&gt;update CSS highlighting for nested selectors in Pygments&lt;/a&gt;, and a
small correction to MDNâ€™s article on the &lt;a href=&quot;https://github.com/mdn/content/pull/45532&quot; title=&quot;Fix wording for return value of anchor() function&quot;&gt;&lt;code&gt;anchor()&lt;/code&gt; CSS function&lt;/a&gt;. The
SVG illustration took a bit less than an hour and the article itself a handful
of hours. The &lt;code&gt;attr()&lt;/code&gt; function came in after I thought â€œinline style looks
ugly, isnâ€™t there a better way?â€� But, hey, I still think this is worth it! ğŸ�¨&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn:phd&quot;&gt;
&lt;p&gt;My PhD advisor told me this is unwise.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:phd&quot; title=&quot;Jump back to footnote 1 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:anchor-support&quot;&gt;
&lt;p&gt;The first bits of anchor positioning are &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/anchor-name#browser_compatibility&quot; title=&quot;Browser compatibility for anchor-name on MDN&quot;&gt;supported&lt;/a&gt; from Chromeâ€¯125 (Mayâ€¯2024), Firefoxâ€¯147 (Januaryâ€¯2026), and Safariâ€¯26 (Septemberâ€¯2025).&lt;/p&gt;
&lt;p&gt;Before Safariâ€¯26.5, sidenotes may collide due to a &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=315704&quot; title=&quot;[anchor-position-1] anchor referencing an anchor of the same name does not resolve to the previous one.&quot;&gt;bug&lt;/a&gt; in how dependency
chains are handled. You can &lt;a href=&quot;https://github.com/vincentbernat/vincent.bernat.ch/blob/1e6299da5c95dfce6549dfb20da2cea7c9e58664/content/media/js/luffy1.sidenotes.js&quot;&gt;detect this situation with some JavaScript&lt;/a&gt;.
It is, however, not needed in the solution described here as we depend on a
more recent feature.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:anchor-support&quot; title=&quot;Jump back to footnote 2 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:runt&quot;&gt;
&lt;p&gt;If you noticed the runt in the first note, I share your pain and lament that
Firefox does not implement &lt;code&gt;text-wrap: pretty&lt;/code&gt;.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:runt&quot; title=&quot;Jump back to footnote 3 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:attr-support&quot;&gt;
&lt;p&gt;Typed &lt;code&gt;attr()&lt;/code&gt; is &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/attr#browser_compatibility&quot; title=&quot;Browser compatibility for attr() on MDN&quot;&gt;supported&lt;/a&gt; from Chromeâ€¯133 (Februaryâ€¯2025),
Firefoxâ€¯155 (Septemberâ€¯2026), and Safariâ€¯27 (Septemberâ€¯2026). Check &lt;a href=&quot;https://una.im/advanced-attr&quot; title=&quot;New capabilities for attr()&quot;&gt;Una
Kravetsâ€™ article&lt;/a&gt; for details. To support more
browsers, you can inline the anchor name and the position anchor directly in
the HTML:&lt;/p&gt;
&lt;div class=&quot;language-html codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;â€¦&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;anchor-name: --lf-sn-â€¦&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#sidenote-â€¦&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;1&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;sup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;â€œ&lt;a href=&quot;https://blog.master.dev/managing-anchor-associations-with-data-attributes-and-advanced-attr/&quot; title=&quot;Managing Anchor Associations With Data Attributes and Advanced attr()&quot;&gt;Managing Anchor Associations With Data Attributes and Advanced
&lt;code&gt;attr()&lt;/code&gt;&lt;/a&gt;,â€� by Daniel Schwarz, explores CSS
anchors and typed &lt;code&gt;attr()&lt;/code&gt; in more detail.Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:attr-support&quot; title=&quot;Jump back to footnote 4 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn:reference&quot;&gt;
&lt;p&gt;The exact rule for the &lt;a href=&quot;https://drafts.csswg.org/css-anchor-position-1/#target-anchor-element&quot; title=&quot;CSS Anchor Positioning: target anchor element&quot;&gt;target anchor element&lt;/a&gt; is more complex: â€œif an
ancestor of [the note] satisfies the following conditions, return the
nearest such element to [the note]. Otherwise, return the last element in
tree order that satisfies the conditions.â€� One of these conditions is that
â€œ[the candidate] is an &lt;a href=&quot;https://drafts.csswg.org/css-anchor-position-1/#acceptable-anchor-element&quot; title=&quot;CSS Anchor Positioning: acceptable anchor element&quot;&gt;acceptable anchor element&lt;/a&gt; for [the note],â€� which
requires that â€œ[the candidate] is laid out strictly before [the note],â€�
where the relevant clause is that â€œ[the candidate] is either not absolutely
positioned or occurs earlier in the flat tree order than [the note].â€�Â &lt;a class=&quot;footnote-backref&quot; href=&quot;https://vincent.bernat.ch#fnref:reference&quot; title=&quot;Jump back to footnote 5 in the text&quot;&gt;â†©&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Mon, 07 Sep 2026 06:49:58 +0000</pubDate>

</item> 
<item>
	<title>Iustin Pop: AI agents aha moment</title>
	<guid>https://k1024.org/posts/2026/2026-09-06-ai-agents-aha/</guid>
	<link>https://k1024.org/posts/2026/2026-09-06-ai-agents-aha/</link>
     <description>  &lt;p&gt;Looking at the reactions to the Debian AI vote, I think some people still think
the clock can be turned back, as if that ever worked in history. Rather than cry
about spilled milk, I prefer to find a path forward in the new world. There are
many ways to use LLMs, some of them are straightforward, others not so much.&lt;/p&gt;
&lt;p&gt;One of the “not so clear” areas for me is the focus on agentic workloads. For
complex tasks, sure, you want something that can work in the background, but in
general, why does every single tool go the agentic way? I much prefer the
“chat/ask” approach, or even the “code” one, but if I’m at the keyboard, why
would I send a task to an agent, and see it work, instead of directly
implementing it?&lt;/p&gt;
&lt;p&gt;And then, this past Friday, I finally understood one part of that. I was in the
airport, sitting at the gate and waiting to board a flight, and because I
arrived much earlier at the airport (fearing crowds due to Labour Day weekend),
I got one hour of work before boarding started. As the time for boarding
approached, I did one more
&lt;a href=&quot;https://github.com/iustin/corydalis/commit/2b2f520952175b626c4d769c4d46825758954ea3&quot;&gt;commit&lt;/a&gt;
after making sure tests pass, pushed, closed laptop, and went to walk a bit
before getting on the plane.&lt;/p&gt;
&lt;p&gt;As I was getting up, I get a phone notification from GitHub that the CI run
&lt;a href=&quot;https://github.com/iustin/corydalis/actions/runs/33935984250/job/101223903306&quot;&gt;failed&lt;/a&gt;.
I was quite surprised, as the local tests passed, so I open the notification,
and realize that tests via &lt;code&gt;make test&lt;/code&gt; vs CI (which additionally uses
&lt;code&gt;--pedantic&lt;/code&gt;) had slightly different settings, and of course I missed a build
warning (which in CI is an error).&lt;/p&gt;
&lt;p&gt;I thought I’d fix that on the plane, but then I saw a “Copilot agent” button in
the mobile app. I was curious what it did, I click it, and I see Copilot
starting a draft &lt;a href=&quot;https://github.com/iustin/corydalis/pull/21&quot;&gt;pull request&lt;/a&gt;, and saying:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thanks for asking me to work on this. I will get started on it and keep this
PR’s description up to date as I form a plan and make progress.&lt;/p&gt;
&lt;p&gt;Fix the failing GitHub Actions job. Analyze the Actions logs, identify the
root cause of the failure, and implement a fix.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then it goes, finds the failure, writes the fix, and tries to run the tests.
Well, it can’t do it (it runs in a restricted container, so no network, so
&lt;code&gt;stack install&lt;/code&gt; couldn’t actually work). The agent sees that, acknowledges it
has no way to validate the fix, but the error message was clear enough that it
was confident the fix is mostly correct, so it sends the pull request.&lt;/p&gt;
&lt;p&gt;I allow full CI to run on the pull request, and go buy a bottle of water. After
that, I check and see that the CI failed again, as not one but two test files
were broken, and I didn’t have &lt;code&gt;--keep-going&lt;/code&gt;, so the build stopped at the first
failure. I write a comment in the pull request, no reaction, I realize I need to
tag Copilot explicitly, I do that, and it starts another investigation.&lt;/p&gt;
&lt;p&gt;I’m waiting now in the boarding queue, with phone in hand, while Copilot is
fixing my bug. While I scan my boarding pass and walk towards the plane, the
pull request is updated, I trigger another CI, it passes, and I merge it.&lt;/p&gt;
&lt;p&gt;And then, it hit me. Agents allow me to make progress while being “not at
keyboard”, whether that’s physically “not at keyboard”, or while working on
something else. Fixing a simple test failure is not something that needs human
attention per se, whereas improving the test layout might be.&lt;/p&gt;
&lt;p&gt;In that airport, using otherwise-unusable downtime, and without explicitly
intending to, I made progress in understanding a different way to use AI. Now I
have three ways to work with LLMs: ask (tutor mode), code (implement my
request), and agent (fix simple or complex problems, autonomously). I still
don’t know about “plan” mode and really complex tasks, like asking it to
implement features from scratch. That will probably be the next area to tackle.&lt;/p&gt;
&lt;p&gt;And today (Sunday), while waiting for a running race to start, I opened GitHub,
and asked Copilot to increase test coverage for a simple module. It did, and yes
it still can’t run tests (I learned in the meantime that you can
&lt;a href=&quot;https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/customize-the-agent-environment&quot;&gt;configure&lt;/a&gt;
the environment in which the agent runs, nice), but after two back-and-forth
messages, I have a &lt;a href=&quot;https://github.com/iustin/corydalis/pull/22&quot;&gt;pull request&lt;/a&gt;
ready to review. All in the 20 minutes before a race, where I could either
browse social media or actually do some meaningful work.&lt;/p&gt;
&lt;p&gt;Checking now my GitHub billing, it looks like all of this Copilot use only cost
$1.92. Yes, that is under two dollars! And while it did use compute resources,
the person across the aisle who watched TikTok or Instagram for half an hour
while waiting for takeoff also consumed a lot of compute, and so do the
gazillion cat videos uploaded to YouTube every day.&lt;/p&gt;
&lt;p&gt;To me, this is another tool in the toolbox, that might one day replace me (as it
did to the 19th-century textile workers), or make me five times more productive
— we’ll see where we end up. In the meantime, I can move faster, and make better
use of my limited free time.&lt;/p&gt;
&lt;p&gt;Enjoy the ride!&lt;/p&gt; </description> 
	<pubDate>Sun, 06 Sep 2026 13:29:50 +0000</pubDate>

</item> 
<item>
	<title>Russell Coker: CoMaps</title>
	<guid>https://etbe.coker.com.au/?p=6288</guid>
	<link>https://etbe.coker.com.au/2026/09/06/comaps/</link>
     <description>  &lt;p&gt;I have just tried &lt;a href=&quot;https://www.comaps.app/&quot;&gt;CoMaps, a free mapping program released under the Apache license [1]&lt;/a&gt;. I have tried it on Android on a Pixel 6a but it also runs on Linux so I’ll try it on a PinePhone or similar at some convenient time. On Android it is in the F-Droid repository among others and for Linux there’s a Flatpak package.&lt;/p&gt;
&lt;p&gt;The data it uses is from &lt;a href=&quot;https://www.openstreetmap.org/&quot;&gt;Open Street Map project [2]&lt;/a&gt; which has extensive and accurate coverage of every place I’ve looked at (Australia and a few other first-world countries). The first thing it does after being installed is start downloading the world data set from Open Street Map and prompt to download the data for the detected region (Melbourne in my case).&lt;/p&gt;
&lt;p&gt;The UI is decent and allows most of the features that I am used to using in Google Maps. The quality of directions seems good, I’ve only tested it with one journey so far which was a 50 minute drive across the city and it gave a set of directions that Google Maps often gives.&lt;/p&gt;
&lt;p&gt;It gives spoken directions which is an important feature but sometimes the way the directions are presented is confusing. When turning off a freeway it didn’t give a spoken direction to do that, it gave a direction to “turn right” which was AFTER leaving the freeway, fortunately the map was clearly displayed.&lt;/p&gt;
&lt;p&gt;In terms of use practices of this program the main difference I recommend is checking which off ramp to use from a freeway before entering the freeway. With Google Maps you can rely on it giving clear directions in that case.&lt;/p&gt;
&lt;p&gt;I recommend this program without reservation. It can do everything that Google Maps does apart from detecting traffic jams because there’s no way of detecting traffic without spying on users. It is designed to preserve user privacy and works well in that regard.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1]&lt;a href=&quot;https://www.comaps.app/&quot;&gt; https://www.comaps.app/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2]&lt;a href=&quot;https://www.openstreetmap.org/&quot;&gt; https://www.openstreetmap.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;yarpp yarpp-related yarpp-related-rss yarpp-template-list&quot;&gt;

&lt;p&gt;Related posts:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2024/09/15/kogan-ax1800-wifi6-mesh/&quot; rel=&quot;bookmark&quot; title=&quot;Kogan AX1800 Wifi6 Mesh&quot;&gt;Kogan AX1800 Wifi6 Mesh&lt;/a&gt; &lt;small&gt;I previously blogged about the difficulties in getting a good...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2012/03/20/introduction-android/&quot; rel=&quot;bookmark&quot; title=&quot;An Introduction to Android&quot;&gt;An Introduction to Android&lt;/a&gt; &lt;small&gt;I gave a brief introductory talk about Android at this...&lt;/small&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etbe.coker.com.au/2011/10/22/occupy-main-street/&quot; rel=&quot;bookmark&quot; title=&quot;Occupy Main Street&quot;&gt;Occupy Main Street&lt;/a&gt; &lt;small&gt;The Occupy Wall St blog has an informative summary of...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Sun, 06 Sep 2026 11:05:50 +0000</pubDate>

</item> 
<item>
	<title>Enrico Zini: Migrating away from .org/.net/.com domains</title>
	<guid>https://www.ezini.eu/blog/2026/migrating-away-from-org-net-com-domains</guid>
	<link>https://www.ezini.eu/blog/2026/migrating-away-from-org-net-com-domains</link>
     <description>  &lt;p&gt;After having witnessed how easy it is for good people to lose a &lt;code&gt;.org&lt;/code&gt; domain
over a fascist tantrum (you can follow the Autistici/Inventati story
&lt;a href=&quot;https://www.inventati.org/campaign/press&quot;&gt;here&lt;/a&gt; and
&lt;a href=&quot;https://keepitfree.ai/&quot;&gt;here&lt;/a&gt;), I&#39;ve started moving all my infrastructure to
&lt;a href=&quot;https://mastodon.ar.al/@aral/117172339747622841&quot;&gt;differently managed TLDs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;enricozini.org&lt;/code&gt; and &lt;code&gt;enricozini.com&lt;/code&gt; will keep being functional for the time
being, as dropping a domain makes it available for squatting and impersonation.&lt;/p&gt;
&lt;p&gt;These new domains are now online, with working web and emails:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ezini.eu&quot;&gt;enricozini.eu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ezini.eu&quot;&gt;ezini.eu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ezini.eu&quot;&gt;ezini.it&lt;/a&gt; (probably equally subject to fascist
  tantrums these days)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It will take ages to migrate countless accounts that are tied to my primary
email address, so better start early.&lt;/p&gt;
&lt;p&gt;Waiting to see what will happen with &lt;a href=&quot;https://www.dotmeow.org/&quot;&gt;.meow&lt;/a&gt; domains,
which I supported despite not identifying as a cat.&lt;/p&gt; </description> 
	<pubDate>Sun, 06 Sep 2026 09:40:04 +0000</pubDate>

</item> 
<item>
	<title>Steinar H. Gunderson: plocate 1.1.25 released</title>
	<guid>http://blog.sesse.net/blog/tech/2026-09-06-09-02_plocate_1_1_25_released.html</guid>
	<link>http://blog.sesse.net/blog/tech/2026-09-06-09-02_plocate_1_1_25_released.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/sesse.png&quot; width=&quot;74&quot; height=&quot;85&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;I&#39;ve released version 1.1.25 of &lt;a href=&quot;https://plocate.sesse.net/&quot;&gt;plocate&lt;/a&gt;.
This time around, there&#39;s two security issues of unknown severity;
if you chain them with other bugs, they could lead to being able to
list files (but of course not their contents) that you should not
normally be able to see. So an update is probably in order; you can
never be too safe these days.&lt;/p&gt;

&lt;p&gt;The full changelog is:&lt;/p&gt;

&lt;pre&gt;plocate 1.1.25, September 6th, 2026

  - Fix two early-exit bugs with multiple databases.
    Reported by Manpreet Singh and Tyler Spivey.

  - Drop setgid properly, including the saved gid.
    Reported by Michal Sekletar, found with the help of Claude Opus 4.6.

  - Fix a potential symlink-checking race in updatedb.
    Reported by Michal Sekletar, found with the help of Claude Opus 4.6.
&lt;/pre&gt;

&lt;p&gt;As usual, you can get it from &lt;a href=&quot;https://plocate.sesse.net/&quot;&gt;the home page&lt;/a&gt;,
or it&#39;s on the way up in Debian unstable.&lt;/p&gt; </description> 
	<pubDate>Sun, 06 Sep 2026 08:02:00 +0000</pubDate>

</item> 
<item>
	<title>Michael Stapelberg: Debian Code Search: Fast TurboPFor with Go SIMD</title>
	<guid>https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/</guid>
	<link>https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/</link>
     <description>  &lt;p&gt;This August, I accomplished what I wanted for many years: I deleted the last cgo
dependency in Debian Code Search! This was made possible by Goâ€™s recently
introduced SIMD support, because now we can implement the TurboPFor integer
compression format as efficiently â€” more efficiently, in fact, by using the
newer AVX512 instruction set! â€” as the reference implementation.&lt;/p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background: Why does DCS need a fast Integer Codec?&lt;/h2&gt;
&lt;p&gt;Debian Code Search (DCS) is a search engine that allows searching all the Open
Source source code within Debian, with either literal search expressions or
regular expression search queries.&lt;/p&gt;
&lt;p&gt;A search engine uses an inverted index: a map from term to documents containing
the term. Each document is typically represented most efficiently by using an
id, so the index consists of many lists of document ids.&lt;/p&gt;
&lt;p&gt;When searching, it is important to quickly decode these lists to answer the
search query. However, there is a point of diminishing returns where the
decoding speed, even though it can still be measurably improved quite a bit, no
longer influences the overall query duration.&lt;/p&gt;
&lt;p&gt;From 2012 (its inception) to 2019, Debian Code Search used to use a small index
format, and queries were fast because the index was kept entirely in RAM. In
2019, I &lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-09-29-dcs-positional-turbopfor-index/&quot;&gt;implemented the new index
format&lt;/a&gt;, which adds an
on-disk positional index. For literal queries (78.2% of DCS queries), querying
the positional index on disk is faster than querying the non-positional index in
RAM.&lt;/p&gt;
&lt;p&gt;The efficient encoding of the TurboPFor format makes it possible to fit such an
index on a mid-sized Hetzner server, which I rent with two 1 TB SSD disks. The
optimized decoder of the C TurboPFor library is what made decoding fast at query
time.&lt;/p&gt;
&lt;p&gt;If you want to dive deeper into the algorithm, see this blog post from February
2019:&lt;/p&gt;



  &lt;div class=&quot;postlink&quot;&gt;
      &lt;div&gt;
	&lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-02-05-turbopfor-analysis/&quot;&gt;&lt;h3&gt;TurboPFor: an analysis&lt;/h3&gt;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;summary&quot;&gt;
	
	
	
	
	&lt;p&gt;
	  &lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-02-05-turbopfor-analysis/&quot;&gt;
	  Motivation I have recently been looking into speeding up Debian Code Search. As a quick reminder, search engines answer queries by consulting an inverted index: a map from term to documents containing that term (called a â€œposting listâ€�). See the Debian Code Search Bachelor Thesis (PDF) for a lot more details.

	  &lt;span class=&quot;readmore&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-02-05-turbopfor-analysis/&quot;&gt;Read more â†’&lt;/a&gt;
	  
	&lt;/p&gt;
      &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;If you want to learn more about the positional index, see this blog post from
September 2019:&lt;/p&gt;



  &lt;div class=&quot;postlink&quot;&gt;
      &lt;div&gt;
	&lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-09-29-dcs-positional-turbopfor-index/&quot;&gt;&lt;h3&gt;Debian Code Search: positional index, TurboPFor-compressed&lt;/h3&gt;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;summary&quot;&gt;
	
	
	
	
	&lt;p&gt;
	  &lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-09-29-dcs-positional-turbopfor-index/&quot;&gt;
	  Over the last few months, I have been developing a new index format for Debian Code Search. This required a lot of careful refactoring, re-implementation, debug tool creation and debugging.
	  &lt;span class=&quot;readmore&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-09-29-dcs-positional-turbopfor-index/&quot;&gt;Read more â†’&lt;/a&gt;
	  
	&lt;/p&gt;
      &lt;/div&gt;
  &lt;/div&gt;


&lt;h2 id=&quot;simd-go&quot;&gt;SIMD in Go&lt;/h2&gt;
&lt;p&gt;For many years, you had the following options for using SIMD instructions in Go:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Hand-writing &lt;a href=&quot;https://go.dev/doc/asm&quot;&gt;Go assembler code&lt;/a&gt;. This is only doable for
small functions, for example
&lt;a href=&quot;https://pkg.go.dev/bytes#IndexByte&quot;&gt;&lt;code&gt;bytes.IndexByte&lt;/code&gt;&lt;/a&gt; is &lt;a href=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.27.1:src/internal/bytealg/indexbyte_amd64.s&quot;&gt;implemented with
hand-written Go
assembly&lt;/a&gt;
(including AVX2).&lt;/li&gt;
&lt;li&gt;Generating Go assembler code with tools like &lt;a href=&quot;https://github.com/mmcloughlin/avo&quot;&gt;Michael McLoughlinâ€™s
â€œAvoâ€�&lt;/a&gt;. This is &lt;a href=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.27.1:src/crypto/internal/fips140/sha256/_asm/sha256block_amd64_avx2.go&quot;&gt;how
&lt;code&gt;crypto/internal/fips140/sha256&lt;/code&gt; uses
AVX2&lt;/a&gt;. While
Avo generator code definitely is higher-level than hand-written assembly, it
is still too close to assembly for my taste.&lt;/li&gt;
&lt;li&gt;Use a C library via &lt;a href=&quot;https://go.dev/wiki/cgo&quot;&gt;cgo&lt;/a&gt; so gcc or clang compiles
SIMD code. Debian Code Search used to use the
&lt;a href=&quot;https://github.com/powturbo/TurboPFor-Integer-Compression&quot;&gt;powturbo/TurboPFor&lt;/a&gt;
C library via cgo for the last 7 years.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The C TurboPFor library has served us well, but Debian Code Search was always
intended to be a project using Go, so I would prefer it if I did not have any C
code in the project.&lt;/p&gt;
&lt;p&gt;Go 1.26 (released in February 2026) introduced the &lt;code&gt;simd/archsimd&lt;/code&gt; package:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 1.26 introduces a new &lt;a href=&quot;https://pkg.go.dev/simd/archsimd&quot;&gt;experimental &lt;code&gt;simd/archsimd&lt;/code&gt;
package&lt;/a&gt;, which can be enabled by setting
the environment variable &lt;code&gt;GOEXPERIMENT=simd&lt;/code&gt; at build time. This package
provides access to architecture-specific SIMD operations. It is currently
available on the &lt;code&gt;amd64&lt;/code&gt; architecture and supports 128-bit, 256-bit, and
512-bit vector types, such as &lt;code&gt;Int8x16&lt;/code&gt; and &lt;code&gt;Float64x8&lt;/code&gt;, with operations such
as &lt;code&gt;Int8x16.Add&lt;/code&gt;. The API is not yet considered stable.&lt;/p&gt;
&lt;p&gt;â€” &lt;a href=&quot;https://go.dev/doc/go1.26#simd&quot;&gt;Go 1.26 Release Notes&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For my 2019 TurboPFor analysis, I implemented &lt;a href=&quot;https://github.com/stapelberg/goturbopfor&quot;&gt;&lt;code&gt;goturbopfor&lt;/code&gt;, a native Go
teaching decoder&lt;/a&gt; (without any SIMD),
because I find Go code easier to follow than C code, especially optimized C
code. My implementation was intentionally not optimized so that the code was
easier to study.&lt;/p&gt;
&lt;p&gt;The TurboPFor format/algorithm has a vector-optimized part: &lt;a href=&quot;https://github.com/stapelberg/goturbopfor/blob/920055ddf6e9106fce2904817eaf96734bf7e26e/goturbopfor.go#L35&quot;&gt;bitpacking comes in
a scalar variant (&lt;code&gt;bitunpack32&lt;/code&gt;) and a vector variant
(&lt;code&gt;bitunpack256v32&lt;/code&gt;)&lt;/a&gt;,
where the vector variant is used for full blocks (256 values) and the scalar
variant is used for remainder blocks (&amp;lt; 256 values).&lt;/p&gt;
&lt;p&gt;When Go 1.26 was released, I used Claude Code to explore whether my native Go
decoderâ€™s &lt;code&gt;bitunpack256v32&lt;/code&gt; function (for the vertical vector layout) could be
implemented using Go SIMD, and the answer was yes, it was possible and it was
faster than without SIMD, but not quite at the level of C TurboPFor. If you let
Claude Code try for long enough, it eventually finds enough optimizations (about
10) to match C performance.&lt;/p&gt;
&lt;p&gt;I donâ€™t want to vibe-code Debian Code Search, though, so I figured I would find
some time to review the SIMD code at some point and see if I could implement
something similar myself.&lt;/p&gt;
&lt;p&gt;Before I found enough time and motivation to complete said review, I discovered
that to not regress real-life query performance by more than 10 to 100
milliseconds (which seems acceptable), I donâ€™t actually need to add SIMD code to
my teaching decoder at all; it would be sufficient to reduce allocations in my
teaching decoder and specialize it per bit width.&lt;/p&gt;
&lt;p&gt;Encouraged by the possibility of using the optimized native Go decoder in Debian
Code Search, I explored whether I could also implement a native Go &lt;em&gt;encoder&lt;/em&gt; so
that I could get rid of the C TurboPFor dependency entirely. The answer is yes,
it is doable in a few days, and it isnâ€™t even that much slower: Go is at 76% of
C, see &lt;a href=&quot;https://github.com/Debian/dcs/commit/e920dc7c5dd3f0e05de1cde3d73b99489f2e1bcb&quot;&gt;Debian/dcs commit
&lt;code&gt;e920dc7&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The goal I set myself at that point was to see if I could learn enough SIMD to
optimize the native Go encoder such that its performance would match how DCS
uses C TurboPFor (via cgo).&lt;/p&gt;
&lt;p&gt;Beating C TurboPFor was possible in 2-3 commits (SIMD and bit width
specialization). To my surprise, Claude Fable 5 pointed out that the encoderâ€™s
block scanning could be done more efficiently using a technique called
positional popcount, and that is &lt;strong&gt;another 2x speed-up&lt;/strong&gt;! ğŸ˜²&lt;/p&gt;
&lt;p&gt;To be clear: I am not saying the Go compiler beats C here. Certainly, the C
compiler can also produce fast AVX512 code and can be used to implement
positional popcount.  When comparing apples to apples, i.e. backporting the
AVX512 kernels and positional popcount technique to C TurboPFor, Go benchmarks a
little slower at â‰ˆ1.4x C.&lt;/p&gt;
&lt;p&gt;This spectacular result (much faster than what DCS had before) got me curious
how far I could push the decoder with SIMD after all. I ended up
matching/exceeding the cgo version here, too!&lt;/p&gt;
&lt;p&gt;The rest of this article explains a few classes of optimizations I encountered
along the way.&lt;/p&gt;
&lt;h2 id=&quot;starting-point&quot;&gt;Starting Point&lt;/h2&gt;
&lt;p&gt;When I wrote &lt;a href=&quot;https://github.com/stapelberg/goturbopfor/&quot;&gt;my &lt;code&gt;goturbopfor&lt;/code&gt; teaching
decoder&lt;/a&gt;, I named its functions to
match the upstream C TurboPFor library, but now I want to get away from names
like &lt;code&gt;p4ndec256v32&lt;/code&gt; â€” they make sense from the TurboPFor perspective, but for
Debian Code Search, we can use cleaner names.&lt;/p&gt;
&lt;p&gt;Before writing any code, I audited how DCS uses integer compression /
decompression.&lt;/p&gt;
&lt;h3 id=&quot;api-design&quot;&gt;API design: BlockEncoder, BlockDecoder and streaming&lt;/h3&gt;
&lt;p&gt;In Debian Code Search, we have the following usage patterns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Partial Indexing:&lt;/strong&gt; When a new package (or package version) enters Debian,
all of its (text) files are indexed. If the &lt;a href=&quot;https://packages.debian.org/forky/hello&quot;&gt;&lt;code&gt;hello-2.12.3-1&lt;/code&gt;
package&lt;/a&gt; (hypothetically) contained
only &lt;code&gt;hello.c&lt;/code&gt; with &lt;code&gt;printf(&quot;hello!\n&quot;);&lt;/code&gt;, we would assign document ID &lt;code&gt;1&lt;/code&gt; to
&lt;code&gt;hello.c&lt;/code&gt; and store in the partial index that trigrams &lt;code&gt;pri&lt;/code&gt;, &lt;code&gt;rin&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;,
&lt;code&gt;ntf&lt;/code&gt;, etc. are all found in doc &lt;code&gt;1&lt;/code&gt; (&lt;code&gt;hello.c&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full Index Merging:&lt;/strong&gt; The many thousands of partial index files (for each
Debian package) are combined into a small handful of large index files: When
searching, it would be expensive to consult thousands of indexes. To merge
multiple partial index files into one larger index (which can then be
efficiently queried), we need to re-encode the partial index files: what used
to be document ID &lt;code&gt;1&lt;/code&gt; in the partial index might be document ID &lt;code&gt;2531&lt;/code&gt; in the
full index.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Querying (searching):&lt;/strong&gt; When users enter search queries, these queries need
to be answered as quickly as possible. The relevant entries in the full
indexes are decoded (in parallel).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For reading the index, we do keep the decoded &lt;code&gt;uint32&lt;/code&gt;s fully in memory, so we
only need &lt;code&gt;DecodeN(input []byte, output []uint32) (read int)&lt;/code&gt;, a function that
reads &lt;code&gt;len(output)&lt;/code&gt; values (&lt;code&gt;uint32&lt;/code&gt;) from &lt;code&gt;input&lt;/code&gt; and returns how many bytes it
consumed.&lt;/p&gt;
&lt;p&gt;For writing the index (both in partial indexing, and when merging), keeping the
entire index in memory is prohibitively expensive, so we need a streaming API,
for decoding and for encoding.&lt;/p&gt;
&lt;p&gt;Ultimately, I converged on the following API:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pforenc&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;BlockEncoder&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// scratch buffers can go here&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// EncodeBlock encodes len(vals)&amp;lt;=256 uint32s into dest (one TurboPFor block).&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;BlockEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeBlock&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// EncodeN calls EncodeBlock in a loop.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;BlockEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeN&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;StreamEncoder&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;be&lt;span style=&quot;color: #bbb;&quot;&gt;   &lt;/span&gt;BlockEncoder&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;256&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// scratch buffers&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// if full, you need to call [EncodeBlock]&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;StreamEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;Add&lt;/span&gt;(val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(full&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;bool&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// EncodeBlock must be called after all data was [Add]ed.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Write the returned buffer to file or send it over the network;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// it is only valid until the next [EncodeBlock] call.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;StreamEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeBlock&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;se.n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// turn an extra EncodeBlock into a no-op&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// â€¦&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This API (the decoder works similarly) allows us to process data in TurboPFor
format without any memory allocations. The types are not safe for concurrent use
by multiple goroutines. The zero value is ready to be used. For the streaming
API, the result only stays valid until the next call.&lt;/p&gt;
&lt;h3 id=&quot;initial-encoder&quot;&gt;Initial Implementation&lt;/h3&gt;
&lt;p&gt;Before we can optimize anything, we need a working decoder and encoder. The
decoder already exists: my &lt;code&gt;goturbopfor&lt;/code&gt; teaching decoder. Next up, I needed an
encoder.&lt;/p&gt;
&lt;p&gt;Writing a TurboPFor encoder has a delightfully simple starting point: You can
encode all values at bit width 32, in little endian, at which point you only
need to add a one-byte TurboPFor block header every 256 values and youâ€™re done:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(be&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;BlockEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeN&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(vals)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;chunk&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;min&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(vals),&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;256&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be.&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeBlock&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals[:chunk])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals[chunk:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(be&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;BlockEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeBlock&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;append&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;AppendUint32&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, this is a terribly inefficient compressor, so after the first commit,
the real work starts: implement each block type until the compression matches
the original C TurboPFor implementation (same output file size), or in other
words: do the reverse of the decoder.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The TurboPFor &lt;strong&gt;bitpacking&lt;/strong&gt; block type (&lt;a href=&quot;https://github.com/Debian/dcs/commit/11eafa3d5d56388c0f0badb0c4b393acc80470e1&quot;&gt;bitpacking implementation
commit&lt;/a&gt;)
encodes a bit stream of variable bit width (where the bit width is in range
&lt;code&gt;0 â‰¤ bitWidth â‰¤ 32&lt;/code&gt;) in &lt;a href=&quot;https://en.wikipedia.org/wiki/Endianness&quot;&gt;little
endian&lt;/a&gt; byte order. By scanning all
values and choosing the smallest bit width that allows representing all
values, this technique saves disk space (compresses).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;bitpacking with exceptions&lt;/strong&gt; block type (&lt;a href=&quot;https://github.com/Debian/dcs/commit/d7b91f6b0ef732cf78eab2c4cd65dab007255197&quot;&gt;bitpacking with exceptions
implementation
commit&lt;/a&gt;)
determines two bit widths: one for values, the other bit width for encoding
exceptions. This allows choosing a lower bit width (that does not cover all
values) compared to the bitpacking block type. A bitmap encodes whether a
value has an exception or not.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;bitpacking with VB exceptions&lt;/strong&gt; block type (&lt;a href=&quot;https://github.com/Debian/dcs/commit/e920dc7c5dd3f0e05de1cde3d73b99489f2e1bcb&quot;&gt;bitpacking with VB
exceptions implementation
commit&lt;/a&gt;)
is a variant which does not use an exception bitmap and encodes exceptions
using a variable byte integer encoding. This is more efficient when there are
few exceptions (less than 20) or the exceptions are very different in bit
width compared to the other values.&lt;/li&gt;
&lt;li&gt;Lastly, the &lt;strong&gt;constant&lt;/strong&gt; block type (&lt;a href=&quot;https://github.com/Debian/dcs/commit/59df3c6e21443496254e263342dd79bfef4ff173&quot;&gt;constant implementation
commit&lt;/a&gt;)
stores just one value on disk. This is useful for all-zero or all-one blocks,
for example.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I found it interesting to realize that the main work of the encoder is to scan
the input values and choose the optimal block type, whereas the actual encoding
itself is cheap in comparison.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Debian/dcs/commit/e920dc7c5dd3f0e05de1cde3d73b99489f2e1bcb&quot;&gt;At this point, we can look at
performance&lt;/a&gt;
and see that the Go encoder is at 76% of the C encoder.&lt;/p&gt;
&lt;p&gt;In all honesty, I could have probably stopped here, but now that the milestone
of a viable replacement was reached, I got curious to see how far it would be
possible to push the encoder (how much work to reach C speeds?) and afterwards,
the decoder, too.&lt;/p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;
&lt;h3 id=&quot;goamd64&quot;&gt;The microarchitecture level: set &lt;code&gt;GOAMD64&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The microarchitecture of a CPU determines which instructions it provides, and
that includes not just SIMD instruction sets (like AVX2), but also other useful
instructions like &lt;code&gt;LZCNT&lt;/code&gt; (Leading Zero Count), which can be used to implement
&lt;a href=&quot;https://pkg.go.dev/math/bits#Len32&quot;&gt;&lt;code&gt;math/bits.Len32&lt;/code&gt;&lt;/a&gt; more efficiently, which
the TurboPFor encoder needs to call on every input value to determine the ideal
bit width.&lt;/p&gt;
&lt;p&gt;Letâ€™s walk through how to set the microarchitecture level when using Go on
64-bit x86 (x86-64).&lt;/p&gt;
&lt;p&gt;Go uses the &lt;a href=&quot;https://go.dev/doc/install/source#environment&quot;&gt;&lt;code&gt;GOARCH&lt;/code&gt; environment
variable&lt;/a&gt; to configure the target
compilation architecture, and I am using the value &lt;code&gt;amd64&lt;/code&gt; to select 64-bit x86
(AVX2 and AVX512 are instruction sets found on x86-64 CPUs). With
&lt;code&gt;GOARCH=amd64&lt;/code&gt;, the architecture-specific variable
&lt;a href=&quot;https://pkg.go.dev/cmd/go#hdr-Environment_variables&quot;&gt;&lt;code&gt;GOAMD64&lt;/code&gt;&lt;/a&gt; configures the
microarchitecture level for which to compile and Go 1.18 &lt;a href=&quot;https://go.dev/wiki/MinimumRequirements#amd64&quot;&gt;introduced these 4
different levels&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;GOAMD64=v1&lt;/code&gt; (default): The baseline. &lt;br /&gt;
Exclusively generates instructions that all 64-bit x86 processors can execute.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GOAMD64=v2&lt;/code&gt;: all v1 instructions, &lt;br /&gt;
plus CMPXCHG16B, LAHF, SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GOAMD64=v3&lt;/code&gt;: all v2 instructions, &lt;br /&gt;
plus AVX, &lt;strong&gt;AVX2&lt;/strong&gt;, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, OSXSAVE.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GOAMD64=v4&lt;/code&gt;: all v3 instructions, &lt;br /&gt;
plus &lt;strong&gt;AVX512F&lt;/strong&gt;, AVX512BW, AVX512CD, AVX512DQ, AVX512VL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In 2026, I generally recommend compiling with &lt;code&gt;GOAMD64=v3&lt;/code&gt; so that functions
like &lt;a href=&quot;https://pkg.go.dev/math/bits#OnesCount8&quot;&gt;&lt;code&gt;bits.OnesCount8&lt;/code&gt;&lt;/a&gt; are
&lt;a href=&quot;https://cs.opensource.google/go/go/+/master:src/cmd/compile/internal/ssa/_gen/AMD64.rules;l=102-115;drc=64ebd027a7c81f784b4b41f8070355d19e73687b&quot;&gt;compiled into intrinsics
(&lt;code&gt;POPCNT&lt;/code&gt;)&lt;/a&gt;
instead of using a lookup table.&lt;/p&gt;
&lt;p&gt;For Intel CPUs, setting &lt;code&gt;GOAMD64=v3&lt;/code&gt; means your programs will only start on
Haswell CPUs (2013) or newer; for AMD CPUs that means Zen 1 (2017) or newer.&lt;/p&gt;
&lt;p&gt;In this specific case (DCS), I am even compiling with &lt;code&gt;GOAMD64=v4&lt;/code&gt;. The &lt;code&gt;v4&lt;/code&gt;
microarchitecture level requires AVX512, which means AMD Zen 4, Zen 5 or newer
(Intelâ€™s story isâ€¦ complicated). Luckily, both my main development PC (Zen 5)
and the Debian Code Search server (Zen 4) are recent enough. Setting
&lt;code&gt;GOAMD64=v4&lt;/code&gt; has little effect on Go 1.27 itself: the only change is that maps
use one less instruction (&lt;code&gt;VPBROADCASTB&lt;/code&gt; instead of &lt;code&gt;PSHUFB&lt;/code&gt;). But compiling
with &lt;code&gt;GOAMD64=v4&lt;/code&gt; allows us to move one more feature check from runtime to
compile time, see &lt;a href=&quot;https://michael.stapelberg.ch/posts/tags/debian/feed.xml#simd-build-tags&quot;&gt;SIMD build tags&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It makes sense to set the microarchitecture level in your benchmark setup so
that you donâ€™t measure the slow fallback implementations. I use &lt;code&gt;export GOAMD64=v4&lt;/code&gt; in my &lt;code&gt;Makefile&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;benchstat&quot;&gt;Benchmarking setup&lt;/h3&gt;
&lt;p&gt;Goâ€™s built-in &lt;a href=&quot;https://pkg.go.dev/testing#hdr-Benchmarks&quot;&gt;&lt;code&gt;testing&lt;/code&gt; package contains support for
benchmarks&lt;/a&gt; which are written in
functions of the form &lt;code&gt;func BenchmarkXxx(b *testing.B)&lt;/code&gt;. The simplest way to run
such benchmarks is &lt;code&gt;go test -bench=.&lt;/code&gt;, but I ended up configuring a few
convenience &lt;code&gt;make&lt;/code&gt; targets, which write results to &lt;code&gt;bench.txt&lt;/code&gt; and compare
against &lt;code&gt;baseline.txt&lt;/code&gt; (the previous commitâ€™s results, usually), using the very
useful &lt;a href=&quot;https://pkg.go.dev/golang.org/x/perf/cmd/benchstat&quot;&gt;&lt;code&gt;benchstat&lt;/code&gt; tool&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-makefile&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;GOTEST&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;go &lt;span style=&quot;color: #007020;&quot;&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# -count=6 gives pâ‰¤0.002 in benchstat:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# https://pkg.go.dev/golang.org/x/perf/cmd/benchstat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;BENCHFLAGS&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;-run&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;^&lt;span style=&quot;color: #bb60d5;&quot;&gt;$$&lt;/span&gt; -bench&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;. -benchtime&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;200000x -count&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# use taskset -c1 to always pin to the same single core,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# avoiding accidental scheduling on different cores on
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# mixed-core CPUs like the Ryzen 9 9950X3D.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;TASKSET&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;taskset -c &lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;BENCH&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;TASKSET&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;GOTEST&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;BENCHFLAGS&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;.PHONY&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt; all test bench bench-baseline bench-relative
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;all&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt; test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bench&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt; test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;BENCH&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; | tee bench.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# Compares compression ratio between C and Go implementation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	benchstat -col /impl -row &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;/n /vals&#39;&lt;/span&gt; -filter &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;-/impl:go-stream .unit:(encoded-bytes)&#39;&lt;/span&gt; bench.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# Compares performance between C (cgo) and Go implementation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	benchstat -col /impl -row &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;/n /vals&#39;&lt;/span&gt; -filter &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;.unit:(Mval/s)&#39;&lt;/span&gt; bench.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bench-baseline&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt; test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;BENCH&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; | tee baseline.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bench-relative&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt; test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;BENCH&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; | tee bench.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	benchstat -filter &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;-/impl:go-stream .unit:(encoded-bytes)&#39;&lt;/span&gt; baseline.txt bench.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	benchstat -filter &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;/impl:go .unit:(Mval/s)&#39;&lt;/span&gt; baseline.txt bench.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;encoded-bytes&lt;/code&gt; and &lt;code&gt;Mval/s&lt;/code&gt; units are custom metrics I am reporting from
the various &lt;a href=&quot;https://go.dev/blog/subtests&quot;&gt;sub-benchmarks&lt;/a&gt;, which are arranged
such that I can filter / report them with &lt;code&gt;benchstat&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The main encoder (and decoder) benchmarks compare 3 different implementations
(cgo, Go, Go with the StreamEncoder API) with a &lt;a href=&quot;https://github.com/Debian/dcs/commit/e4161bebabcf229734f2dc7a9b54c33caa32875a&quot;&gt;number of benchmark
cases&lt;/a&gt;
that are designed to cover the different block types and contain a similar mix
of values as what we see in Debian Code Search:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// reportMetrics adds Mval/s and encoded-bytes metrics to all benchmarks.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;reportMetrics&lt;/span&gt;(b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;testing.B,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;nencoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;   &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;ReportMetric&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;float64&lt;/span&gt;(nencoded),&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;encoded-bytes&quot;&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;   &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;ReportMetric&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;float64&lt;/span&gt;(b.N&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;n)&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1e6&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Elapsed&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;Seconds&lt;/span&gt;(),&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;Mval/s&quot;&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// BenchmarkEncode/n=&amp;lt;N&amp;gt;/vals=&amp;lt;testcase&amp;gt;/impl=&amp;lt;c|go|go-stream&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// e.g. BenchmarkEncode/n=2048/vals=one-constant/impl=go-stream&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;BenchmarkEncode&lt;/span&gt;(b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;testing.B)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;   &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;tc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;allBenchCases&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;     &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(tc.vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;     &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Run&lt;/span&gt;(fmt.&lt;span style=&quot;color: #06287e;&quot;&gt;Sprintf&lt;/span&gt;(&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;n=%d/vals=%s&quot;&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;tc.name),&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;(b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;testing.B)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;       &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Run&lt;/span&gt;(&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;impl=c&quot;&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;(b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;testing.B)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;ReportAllocs&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;buf&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;make&lt;/span&gt;([]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;turbopfor.&lt;span style=&quot;color: #06287e;&quot;&gt;EncodingSize&lt;/span&gt;(n))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Loop&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;           &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;turbopfor.&lt;span style=&quot;color: #06287e;&quot;&gt;P4nenc256v32Buf&lt;/span&gt;(buf,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;tc.vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;reportMetrics&lt;/span&gt;(b,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(encoded))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;       &lt;/span&gt;})&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;       &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Run&lt;/span&gt;(&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;impl=go&quot;&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;(b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;testing.B)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;ReportAllocs&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;BlockEncoder&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;buf&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;make&lt;/span&gt;([]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;turbopfor.&lt;span style=&quot;color: #06287e;&quot;&gt;EncodingSize&lt;/span&gt;(n))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Loop&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;           &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be.&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeN&lt;/span&gt;(buf,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;tc.vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;reportMetrics&lt;/span&gt;(b,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(encoded))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;       &lt;/span&gt;})&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;       &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Run&lt;/span&gt;(&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;impl=go-stream&quot;&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;(b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;testing.B)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;ReportAllocs&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;se&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;StreamEncoder&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b.&lt;span style=&quot;color: #06287e;&quot;&gt;Loop&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;           &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;           &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;tc.vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;             &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;se.&lt;span style=&quot;color: #06287e;&quot;&gt;Add&lt;/span&gt;(val)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;               &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(se.&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeBlock&lt;/span&gt;())&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;             &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;           &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;           &lt;/span&gt;encoded&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(se.&lt;span style=&quot;color: #06287e;&quot;&gt;EncodeBlock&lt;/span&gt;())&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;reportMetrics&lt;/span&gt;(b,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;encoded)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;       &lt;/span&gt;})&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;     &lt;/span&gt;})&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;   &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;perf&quot;&gt;CPU counters: perf&lt;/h3&gt;
&lt;p&gt;Go has included excellent performance tooling for many years, see the
&lt;a href=&quot;https://go.dev/blog/pprof&quot;&gt;â€œProfiling Go Programsâ€� blog post&lt;/a&gt; (2011) for an
example of how to use &lt;code&gt;pprof&lt;/code&gt;, a sampling profiler. This profiler can help track
down which part of a program runs slow, or where memory allocations happen.&lt;/p&gt;
&lt;p&gt;Once you identified the slow part of a program, how do you know why itâ€™s slow?&lt;/p&gt;
&lt;p&gt;To learn more about the specific bottlenecks your program encounters, you can
consult your CPUâ€™s &lt;a href=&quot;https://en.wikipedia.org/wiki/Hardware_performance_counter&quot;&gt;hardware performance
counters&lt;/a&gt;. For
example, you could check the &lt;a href=&quot;https://en.wikipedia.org/wiki/Branch_predictor&quot;&gt;branch
predictor&lt;/a&gt; counters to see if
your program is slow due to a high number of branch mispredicts.&lt;/p&gt;
&lt;p&gt;On Linux, the &lt;code&gt;perf&lt;/code&gt; tool is the best way to access the CPU hardware performance
counters. A good starting point for working with &lt;code&gt;perf&lt;/code&gt; is the &lt;a href=&quot;https://perfwiki.github.io/main/top-down-analysis/&quot;&gt;documentation on
â€œTop-down analysis with the perf
toolâ€�&lt;/a&gt;, which describes the
optimization method that Intel established.&lt;/p&gt;
&lt;p&gt;In my &lt;code&gt;Makefile&lt;/code&gt;, I set up two &lt;code&gt;perf&lt;/code&gt; targets:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-makefile&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# GOTEST and TASKSET like shown in the earlier benchmarking setup section:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;GOTEST&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;go &lt;span style=&quot;color: #007020;&quot;&gt;test&lt;/span&gt; -pgo&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;encode.cpuprof
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;TASKSET&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;taskset -c &lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bb60d5;&quot;&gt;PERFBENCHFLAGS&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;-test.bench&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;Encode/n=2048/vals=debian-mix/impl=go$$&#39;&lt;/span&gt; -test.benchtime&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;200000x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# Use perf(1) to capture AMD IBS (the equivalent to Intel PEBS)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# PipelineL1 is roughly equivalent to Intel TopdownL1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;perf&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;GOTEST&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; -c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;TASKSET&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; perf stat -M PipelineL1 ./pforenc.test -test.run&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;^&lt;span style=&quot;color: #bb60d5;&quot;&gt;$$&lt;/span&gt; &lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;PERFBENCHFLAGS&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	sudo perf record -F &lt;span style=&quot;color: #40a070;&quot;&gt;4999&lt;/span&gt; -e ibs_op// --call-graph fp ./pforenc.test -test.run&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;^&lt;span style=&quot;color: #bb60d5;&quot;&gt;$$&lt;/span&gt; &lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;PERFBENCHFLAGS&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	sudo chmod &lt;span style=&quot;color: #40a070;&quot;&gt;644&lt;/span&gt; perf.data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;# 488281 iterations Ã— 2048 values = 1.000e9 values, so counter/1e9 = per value.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;perf-per-value&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;GOTEST&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; -c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;$(&lt;/span&gt;TASKSET&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;)&lt;/span&gt; perf stat -x, -e cycles:u,instructions:u,branches:u,branch-misses:u ./pforenc.test -test.run&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;^&lt;span style=&quot;color: #bb60d5;&quot;&gt;$$&lt;/span&gt; -test.bench&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;Encode/n=2048/vals=debian-mix/impl=go$$&#39;&lt;/span&gt; -test.benchtime&lt;span style=&quot;color: #666;&quot;&gt;=&lt;/span&gt;488281x 2&amp;gt;&amp;amp;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt; &amp;gt;/dev/null | awk -F, &lt;span style=&quot;color: #4070a0;&quot;&gt;&#39;{printf &quot;%-16s %6.2f /val\n&quot;, $$3, $$1/1e9}&#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;perf-per-value&lt;/code&gt; numbers are high level numbers that indicate how much work
the implementation is doing. Reducing the number usually increases speed.&lt;/p&gt;
&lt;p&gt;To see the counters for each instruction (and source code lines), I use &lt;code&gt;make perf&lt;/code&gt;, followed by &lt;code&gt;perf report&lt;/code&gt;. A quick shortcut is &lt;code&gt;perf annotate&lt;/code&gt;, which
directly shows the hottest function.&lt;/p&gt;
&lt;h2 id=&quot;opt-scalar&quot;&gt;Optimizations (scalar)&lt;/h2&gt;
&lt;p&gt;Letâ€™s first see how far we can get without reaching for SIMD instructions.&lt;/p&gt;
&lt;p&gt;(The examples are not necessarily in commit order, but cherry-picked for clarity.)&lt;/p&gt;
&lt;h3 id=&quot;pgo&quot;&gt;Profile-Guided Optimization (PGO)&lt;/h3&gt;
&lt;p&gt;PGO stands for Profile-Guided Optimization and is a feature that Go introduced
as a preview in Go 1.20 (released in February 2023) and shipped as &lt;a href=&quot;https://go.dev/blog/pgo&quot;&gt;ready for
general production use in Go 1.21&lt;/a&gt; (released in August
2023).&lt;/p&gt;
&lt;p&gt;The idea is to capture a CPU profile that records where your program spends most
of its CPU time, which you then provide to the Go compiler to give it more data
to make better decisions.&lt;/p&gt;
&lt;p&gt;Most importantly, this way the Go compiler can &lt;a href=&quot;https://go.dev/blog/pgo#inlining&quot;&gt;inline functions much more
aggressively&lt;/a&gt; than its usual heuristics allow,
which does have a measurably positive effect in my series of optimization
commits. Another optimization that a PGO profile allows the compiler to do is
&lt;a href=&quot;https://go.dev/blog/pgo#devirtualization&quot;&gt;conditional devirtualization&lt;/a&gt; â€” but
our TurboPFor code does not use any interfaces.&lt;/p&gt;
&lt;p&gt;My strategy is to enable PGO before doing any other optimizations, so that we
have the full inlining budget available that PGO gives us, and can measure the
effect of other commits clearly.&lt;/p&gt;
&lt;p&gt;Surprisingly, &lt;a href=&quot;https://github.com/Debian/dcs/commit/d6a44a18b376bf7b33fa01b8c69fa448c776a0f0&quot;&gt;turning on PGO actually decreases our
performance&lt;/a&gt;
(-13% geomean), but a closer investigation reveals that we just got unlucky. Let
me explain.&lt;/p&gt;
&lt;p&gt;Aside from inlining and conditional devirtualization, PGO also influences
alignment: The Go compiler sets &lt;code&gt;PCALIGNMAX(64, 31)&lt;/code&gt; on the first block of a
loop (the â€œloop bodyâ€�) for all loops in hot functions (per the PGO profile),
i.e. Go will insert up to 31 bytes of padding to make the block land on a
64-byte boundary. Documentation like &lt;a href=&quot;https://docs.amd.com/v/u/en-US/58455_1.00&quot;&gt;AMDâ€™s â€œSoftware Optimization Guide for the
AMD Zen5 Microarchitectureâ€�&lt;/a&gt; (2024,
#58455) explicitly recommends aligning hot loops that way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[â€¦] for hot loops, some further knowledge of trade-offs can be
helpful. Because the processor can read an aligned 64-byte fetch block every
cycle, it is suggested to either align the start of the loop to the beginning
of a 64-byte cache line [â€¦]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Indeed, when compiling with &lt;code&gt;-gcflags=all=-d=alignhot=0&lt;/code&gt; to disable the
alignment, performance remains as good as without PGO. How can the padding hurt
more than help?  The answer is: Itâ€™s not the padding itself! Itâ€™s a side-effect
of the padding moving instructions to different addresses.&lt;/p&gt;
&lt;p&gt;In the unlucky arrangement, a macro-fused &lt;code&gt;CMPQ&lt;/code&gt;+&lt;code&gt;JGE&lt;/code&gt; instruction pair now ends
up &lt;em&gt;exactly on a 32-byte boundary&lt;/em&gt;. However, the Go compiler ensures fused
branch sequences &lt;em&gt;must never cross or end at a 32-byte boundary&lt;/em&gt; to &lt;a href=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.27.0:src/cmd/internal/obj/x86/asm6.go;l=1978-2020;drc=aee6009ba5e1d71948b03ac0458fbc99e3a14ace&quot;&gt;fix Intel
erratum
SKX102&lt;/a&gt;
(discussion: &lt;a href=&quot;https://github.com/golang/go/issues/35881&quot;&gt;Go issue #35881&lt;/a&gt;) by
inserting &lt;code&gt;NOP&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;NOP&lt;/code&gt; padding, unlike the loop alignment padding, is not free; these extra
instructions slow down our otherwise dispatch-bound loops.&lt;/p&gt;
&lt;p&gt;Because the commits after the PGO enabling commit change the code, this unlucky
situation is avoided for the rest of the optimization series (by chance).&lt;/p&gt;
&lt;h3 id=&quot;reducing-allocations&quot;&gt;Reducing memory allocations&lt;/h3&gt;
&lt;p&gt;Memory allocations are quite expensive, at least in comparison to
encoding/decoding integers, so I followed my usual strategy of first reducing
memory allocations as much as possible.&lt;/p&gt;
&lt;p&gt;In my &lt;code&gt;goturbopfor&lt;/code&gt; teaching decoder, whenever the code needed a scratch buffer,
it would allocate it right then and there with &lt;code&gt;make()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// p4dec32 decodes one block of TurboPFor-encoded 32 bit ints&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(d&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;decoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;p4dec32&lt;/span&gt;(input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(read&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// â€¦&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;switch&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockType&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpackingExceptions:&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;bx,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;],&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(output)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;exmap&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// number of exceptions&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exmap[i&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(i&lt;span style=&quot;color: #666;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;))&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;nex&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[(n&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;)&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;exceptions&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;make&lt;/span&gt;([]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;nex)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[&lt;span style=&quot;color: #06287e;&quot;&gt;bitunpack32&lt;/span&gt;(input,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exceptions,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bx):]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[d.&lt;span style=&quot;color: #06287e;&quot;&gt;bitunpack&lt;/span&gt;(input,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;output,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b):]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exmap[i&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(i&lt;span style=&quot;color: #666;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;))&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;output[i]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exceptions[&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;exceptions&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exceptions[&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;before&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(input)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Go compiler can turn &lt;code&gt;make(T, n)&lt;/code&gt; calls into stack allocations, if &lt;code&gt;n&lt;/code&gt; is
known at compile-time. But, in this case &lt;code&gt;nex&lt;/code&gt; is not known at compile-time. We
can verify that Go calls into the runtime (&lt;code&gt;runtime.makeslice&lt;/code&gt;) by dumping the
object code (assembly) with source annotated (&lt;code&gt;-S&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;% cd ~/go/src/github.com/stapelberg/goturbopfor
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;% git reset --hard 49b7c05cc61e77f0257568eb73833467714d2b4a
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;% go test -c  # go1.27.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;% go tool objdump -S goturbopfor.test | perl -nlE &#39;say if /p4dec32/ .. /^$/&#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;TEXT github.com/stapelberg/goturbopfor.(*decoder).p4dec32(SB) /home/michael/go/src/github.com/stapelberg/goturbopfor/goturbopfor.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;func (d *decoder) p4dec32(input []byte, output []uint32) (read int) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f60		4c8da42460ffffff	LEAQ 0xffffff60(SP), R12
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f68		4d3b6610		CMPQ R12, 0x10(R14)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f6c		0f86d9070000		JBE 0x54a74b
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f72		55			PUSHQ BP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f73		4889e5			MOVQ SP, BP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f76		4881ec18010000		SUBQ $0x118, SP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f7d		48899c2430010000	MOVQ BX, 0x130(SP)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f85		4889b42448010000	MOVQ SI, 0x148(SP)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;	if len(output) == 0 {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f8d		4d85c0			TESTQ R8, R8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f90		0f84a7030000		JE 0x54a33d
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f96		660f1f840000000000	NOPW 0(AX)(AX*1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;  0x549f9f		90			NOPL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;[â€¦]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;		exceptions := make([]uint32, nex)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;  0x54a4be		488d057bec1700		LEAQ 0x17ec7b(IP), AX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;  0x54a4c5		4c89fb			MOVQ R15, BX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;  0x54a4c8		4889d9			MOVQ BX, CX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;  0x54a4cb		e8f0ddf3ff		CALL runtime.makeslice(SB)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;[â€¦]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An easy speed-up was to &lt;a href=&quot;https://github.com/stapelberg/goturbopfor/commit/3c530dbcfc8fe01674e3168c296fcfdf3d06718c&quot;&gt;avoid allocations through
reuse&lt;/a&gt;
(in &lt;code&gt;goturbopfor&lt;/code&gt;). In the DCS &lt;code&gt;pfordec&lt;/code&gt; package (with the &lt;a href=&quot;https://michael.stapelberg.ch/posts/tags/debian/feed.xml#api-design&quot;&gt;improved
API design&lt;/a&gt;), I ended up with a &lt;code&gt;vals [256]uint32&lt;/code&gt; field in the &lt;code&gt;StreamDecoder&lt;/code&gt;
type, which brings us from 773 Mval/s to 858 Mval/s on the debian-mix:&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;% benchstat -filter &#39;/impl:go /vals:debian-mix .unit:(Mval/s)&#39; \
  baseline.txt bench.txt
goos: linux
goarch: amd64
pkg: github.com/Debian/dcs/internal/turbopfor/pfordec
cpu: AMD Ryzen 9 9950X3D 16-Core Processor
           â”‚ baseline.txt â”‚             bench.txt              â”‚
           â”‚    Mval/s    â”‚   Mval/s     vs base               â”‚
n=2048        1.089k Â± 1%   1.175k Â± 0%   +7.85% (p=0.002 n=6)
n=2039         974.7 Â± 0%   1046.0 Â± 0%   +7.32% (p=0.002 n=6)
n=160          434.9 Â± 1%    513.6 Â± 5%  +18.11% (p=0.002 n=6)
geomean        772.9         857.7       +10.98%
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Aside from the speed-up, avoiding memory allocations is generally nice in
benchmarks because it removes the garbage collector from the equation and makes
it less likely that your benchmarks get other processes OOM-killed on the same
machine.&lt;/p&gt;
&lt;h3 id=&quot;bit-width-specialization&quot;&gt;Generics for bit width specialization&lt;/h3&gt;
&lt;p&gt;In general, we want to make it easy for the compiler to understand as much as
possible about our algorithm. Consider this &lt;code&gt;bitpack&lt;/code&gt; implementation:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitpack&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;mask&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;|=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(val&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;mask)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;AppendUint32&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;append&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;byte&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Letâ€™s think through what determines the iterations and control flow this
function uses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;em&gt;number of input values&lt;/em&gt; (&lt;code&gt;vals&lt;/code&gt;), but not their actual value.&lt;/li&gt;
&lt;li&gt;The bit width to pack into (&lt;code&gt;bitWidth&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With a bit of careful rearrangement, we can provide the compiler with both, a
fixed number of input values (say, 32), and a bit width, both known at compile
time. Why is this worthwhile? Because we can manually unroll the loop, let the
compiler eliminate much of the repetition and get much faster compiled code as a
result!&lt;/p&gt;
&lt;p&gt;Letâ€™s first fix the number of input values to 32 and rewrite the loop to
calculate the position offsets within &lt;code&gt;dest&lt;/code&gt; instead of changing &lt;code&gt;dest&lt;/code&gt; on each
value (with &lt;code&gt;AppendUint32&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitpack32Unrolled&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// only one bounds check for 32 values&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest[:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;bitWidth]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;mask&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Manually unrolled loop starts here.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Each iteration is identical except for the vals[x] index.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;|=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(vals[&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;mask)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;PutUint32&lt;/span&gt;(dest[pos:pos&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;],&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// vals[1] .. vals[30] elided for brevity&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Each loop iteration is 8 lines of Go code, so for 32 input values,&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// bitpack32Unrolled contains 8*32 = 256 lines of code.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;|=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(vals[&lt;span style=&quot;color: #40a070;&quot;&gt;31&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;mask)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;PutUint32&lt;/span&gt;(dest[pos:pos&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;],&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// have == 0; for all bitWidths&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we want to specialize not just for 32 input values, but also for each of
the 32 bit widths.&lt;/p&gt;
&lt;p&gt;Can we do better than hand-copying &lt;code&gt;bitpack32Unrolled&lt;/code&gt; 32 times (= 8192 lines of Go code)?&lt;/p&gt;
&lt;p&gt;Yes, we can use Go generics to help us with the code generation!&lt;/p&gt;
&lt;p&gt;In Go, &lt;a href=&quot;https://go.dev/ref/spec#Array_types&quot;&gt;array types&lt;/a&gt; like &lt;code&gt;[4]byte&lt;/code&gt; (not
slices like &lt;code&gt;[]byte&lt;/code&gt;!)  contain the length of the array as part of their type,
meaning &lt;code&gt;[1]byte&lt;/code&gt; (an array of length 1) is a different type than &lt;code&gt;[2]byte&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Instead of passing the bit width as a function parameter, we can declare 32
&lt;em&gt;different types&lt;/em&gt; (one for each bit width) and recover the bit width (at compile
time!) from the type system:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidthT&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;2&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;3&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;5&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;6&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;9&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;10&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;11&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;12&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;13&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;14&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;15&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;17&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;18&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;19&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;20&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;21&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;22&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;23&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;24&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;25&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;26&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;27&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;28&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;29&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;30&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;31&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;|&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[T&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidthT](dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;zero&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;T&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(zero)&lt;span style=&quot;color: #bbb;&quot;&gt;                  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// known at compile time&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest[:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;bitWidth]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// make cap known at compile time&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;mask&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Manually unrolled loop starts here.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Each iteration is identical except for the vals[x] index.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;|=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(vals[&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;mask)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;PutUint32&lt;/span&gt;(dest[pos:pos&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;],&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// vals[1] .. vals[31] elided for brevity&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we instantiate &lt;code&gt;bitpack32Unrolled[bitWidthT]&lt;/code&gt; with all 32 different types
(&lt;code&gt;[1]byte&lt;/code&gt;, &lt;code&gt;[2]byte&lt;/code&gt;, â€¦, &lt;code&gt;[32]byte&lt;/code&gt;), the compiler substitutes the &lt;code&gt;bitWidthT&lt;/code&gt;
type parameter and produces 32 copies of the function, which we can find in our
compiled executable with names like
&lt;code&gt;github.com/Debian/dcs/internal/turbopfor/pforenc.bitpack32Unrolled[go.shape.[12]uint8]&lt;/code&gt;. The
â€œshapeâ€� of a generic type is based on its memory layout, so a shape for
&lt;code&gt;[1]byte&lt;/code&gt; must be different than the shape for &lt;code&gt;[2]byte&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Because the &lt;code&gt;bitWidth&lt;/code&gt; is now known at compile time, the Go compiler can
generate close to the optimal machine code for each bit width, which we can
confirm using &lt;code&gt;go tool objdump&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The code is branchless (after the one bounds check per 32 values) and aside from
the loads and stores (from/to memory) consists only of shifts and bit
operations, all with constant operands:&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;% go test -c &amp;amp;&amp;amp; go tool objdump -S pforenc.test
[â€¦]
TEXT github.com/Debian/dcs/internal/turbopfor/pforenc.bitpack32Unrolled[go.shape.[28]uint8](SB) /home/michael/dcs/internal/turbopfor/pforenc/bitpackunroll.go
func bitpack32Unrolled[T bitWidthT](dest []byte, vals *[32]uint32) {
  0x660580              55                      PUSHQ BP
  0x660581              4889e5                  MOVQ SP, BP
  0x660584              48895c2418              MOVQ BX, 0x18(SP)
        dest = dest[: 4*bitWidth : 4*bitWidth] // make cap known at compile time
  0x660589              4883ff70                CMPQ DI, $0x70
  0x66058d              0f820b030000            JB 0x66089e
        acc |= uint64(vals[0]&amp;amp;mask) &amp;lt;&amp;lt; have
  0x660593              8b06                    MOVL 0(SI), AX
  0x660595              25ffffff0f              ANDL $0xfffffff, AX
        acc |= uint64(vals[1]&amp;amp;mask) &amp;lt;&amp;lt; have
  0x66059a              8b4e04                  MOVL 0x4(SI), CX
  0x66059d              81e1ffffff0f            ANDL $0xfffffff, CX
  0x6605a3              48c1e11c                SHLQ $0x1c, CX
  0x6605a7              4809c8                  ORQ CX, AX
                acc &amp;gt;&amp;gt;= 32
  0x6605aa              4889c1                  MOVQ AX, CX
  0x6605ad              48c1e820                SHRQ $0x20, AX
                binary.LittleEndian.PutUint32(dest[pos:pos+4], uint32(acc))
  0x6605b1              90                      NOPL
        b[0] = byte(v)
  0x6605b2              890b                    MOVL CX, 0(BX)
        acc |= uint64(vals[2]&amp;amp;mask) &amp;lt;&amp;lt; have
  0x6605b4              8b4e08                  MOVL 0x8(SI), CX
  0x6605b7              81e1ffffff0f            ANDL $0xfffffff, CX
  0x6605bd              48c1e118                SHLQ $0x18, CX
  0x6605c1              4809c1                  ORQ AX, CX
                acc &amp;gt;&amp;gt;= 32
  0x6605c4              4889c8                  MOVQ CX, AX
  0x6605c7              48c1e920                SHRQ $0x20, CX
                binary.LittleEndian.PutUint32(dest[pos:pos+4], uint32(acc))
  0x6605cb              90                      NOPL
        b[0] = byte(v)
  0x6605cc              894304                  MOVL AX, 0x4(BX)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we need to actually call &lt;code&gt;bitpack32&lt;/code&gt; from the general &lt;code&gt;bitpack&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitpack&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// no payload, sparse block with only exceptions&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(vals)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(vals)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;existing&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(dest)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;slices.&lt;span style=&quot;color: #06287e;&quot;&gt;Grow&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;size)[:existing&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;size]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitpack32&lt;/span&gt;(dest[existing:]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;/*append*/&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)(vals),&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;mask&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;|=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(val&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;mask)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;AppendUint32&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;append&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;byte&lt;/span&gt;(acc))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;have&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitpack32&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;switch&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;2&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;2&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;3&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;3&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;5&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;5&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;6&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;6&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;9&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;9&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;10&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;10&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;11&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;11&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;12&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;12&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;13&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;13&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;14&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;14&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;15&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;15&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;17&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;17&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;18&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;18&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;19&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;19&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;20&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;20&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;21&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;21&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;22&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;22&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;23&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;23&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;24&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;24&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;25&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;25&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;26&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;26&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;27&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;27&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;28&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;28&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;29&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;29&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;30&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;30&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;31&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;31&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitpack32Unrolled[[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;](dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Encoding remainder blocks is quite a bit faster (full blocks use the vertical
layout anyway):&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;% benchstat -filter &#39;/impl:go /n:160 .unit:(Mval/s)&#39; baseline.txt bench.txt
goos: linux
goarch: amd64
pkg: github.com/Debian/dcs/internal/turbopfor/pforenc
cpu: AMD Ryzen 9 9950X3D 16-Core Processor
                         â”‚ baseline.txt â”‚             bench.txt              â”‚
                         â”‚    Mval/s    â”‚   Mval/s     vs base               â”‚
vals=bitpacking-bw1          751.2 Â± 3%   1120.5 Â± 0%  +49.15% (p=0.002 n=6)
vals=bitpacking-bw2          716.8 Â± 2%   1176.0 Â± 0%  +64.07% (p=0.002 n=6)
vals=bitpacking-bw7          700.0 Â± 1%   1078.5 Â± 0%  +54.08% (p=0.002 n=6)
vals=bitpacking-bw1-exc      524.8 Â± 1%    736.8 Â± 0%  +40.40% (p=0.002 n=6)
vals=bitpacking-bw2-exc      543.7 Â± 1%    758.2 Â± 0%  +39.46% (p=0.002 n=6)
vals=bitpacking-bw7-exc      566.7 Â± 1%    787.7 Â± 0%  +38.99% (p=0.002 n=6)
vals=bitpacking-vb-exc       442.6 Â± 1%    616.5 Â± 0%  +39.29% (p=0.002 n=6)
vals=sparse-exc              532.4 Â± 0%    787.8 Â± 0%  +47.97% (p=0.002 n=6)
vals=sparse-vb-exc           408.9 Â± 1%    597.8 Â± 0%  +46.20% (p=0.002 n=6)
vals=debian-mix              559.5 Â± 0%    783.8 Â± 9%  +40.09% (p=0.002 n=6)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This performance win comes at the cost of binary size increase. In this case,
the &lt;code&gt;.text&lt;/code&gt; section (executable code) grows by about 20 KB and the &lt;code&gt;.gopclntab&lt;/code&gt;
section grows by another 26 KB. Definitely a price I am very willing to pay, but
the case might not be as clear in all circumstances.&lt;/p&gt;
&lt;h2 id=&quot;simd-bigger-strides&quot;&gt;Optimization: Bigger strides with SIMD&lt;/h2&gt;
&lt;p&gt;Even without reaching for SIMD instructions, a TurboPFor implementation can be
made faster by making it work bigger strides. Take this code from the
&lt;code&gt;goturbopfor&lt;/code&gt; teaching decoder which counts the number of exceptions by checking
if each valueâ€™s bit is set in the exception bitmap:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpackingExceptions:&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;bx,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;],&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(output)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;exmap,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[(n&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;)&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// number of exceptions&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exmap[i&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(i&lt;span style=&quot;color: #666;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;))&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;nex&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;exceptions&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;d.scratch[:nex]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can use the &lt;a href=&quot;https://pkg.go.dev/math/bits#OnesCount64&quot;&gt;&lt;code&gt;bits.OnesCount64&lt;/code&gt;&lt;/a&gt;
functions to count ones bits in the exception bitmap, 64 values at a time. For
remainder blocks, the rest is processed 8 values (1 byte) at a time:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;xm8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;Uint64&lt;/span&gt;(exmap[i:])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits.&lt;span style=&quot;color: #06287e;&quot;&gt;OnesCount64&lt;/span&gt;(xm8)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(n&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;)&lt;span style=&quot;color: #666;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;xmb&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;exmap[i]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Clear the bits which do not belong to the exception map:&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;rem&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;rem&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;xmb&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;rem&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Go compiles OnesCount32 into an intrinsic,&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// but not OnesCount8, so we convert to uint32:&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits.&lt;span style=&quot;color: #06287e;&quot;&gt;OnesCount32&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(xmb))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;OnesCount64&lt;/code&gt; uses a 64-bit register. For comparison, AVX2 SIMD instructions use
256-bit registers (= 8 &lt;code&gt;uint32&lt;/code&gt;) and AVX512 SIMD instructions use 512-bit registers.&lt;/p&gt;
&lt;p&gt;In the following sections, we will first set up our build tags for conditional
compilation to use a trivial SIMD instruction, then walk through an AVX2 and
AVX512 SIMD kernel.&lt;/p&gt;
&lt;h3 id=&quot;simd-build-tags&quot;&gt;SIMD build tags&lt;/h3&gt;
&lt;p&gt;Letâ€™s assume we have the following scalar code:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;constant.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pfordec&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstant&lt;/span&gt;(output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;output[i]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To increase throughput, we can use AVX2 instructions if they are available on the CPU on which the program runs, i.e. using runtime dispatch. Weâ€™ll first rename &lt;code&gt;fillConstant&lt;/code&gt; to &lt;code&gt;fillConstantScalar&lt;/code&gt; (itâ€™s now the fallback path):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;constant.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pfordec&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstantScalar&lt;/span&gt;(output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;output[i]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, weâ€™ll supply two different implementations (&lt;code&gt;constant_nosimd.go&lt;/code&gt; and &lt;code&gt;constant_amd64.go&lt;/code&gt;), the latter of which is selected when compiling for &lt;code&gt;GOARCH=amd64&lt;/code&gt; with &lt;code&gt;GOEXPERIMENT=simd&lt;/code&gt; (the latter will hopefully be dropped in a later version of Go). The &lt;code&gt;nosimd&lt;/code&gt; variant just dispatches to the &lt;code&gt;fillConstantScalar&lt;/code&gt;, which will likely be inlined:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;//go:build !goexperiment.simd || !amd64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pfordec&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstant&lt;/span&gt;(output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstantScalar&lt;/span&gt;(output,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;constant_amd64.go&lt;/code&gt; variant assigns the &lt;code&gt;hasAVX2&lt;/code&gt; global variable by doing a &lt;code&gt;CPUID&lt;/code&gt; check and then jumps to the scalar fallback if &lt;code&gt;!hasAVX2&lt;/code&gt;, i.e. the CPU is too old:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;//go:build goexperiment.simd &amp;amp;&amp;amp; amd64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pfordec&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;simd/archsimd&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;hasAVX2&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.X86.&lt;span style=&quot;color: #06287e;&quot;&gt;AVX2&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstant&lt;/span&gt;(output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;!hasAVX2&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstantScalar&lt;/span&gt;(output,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;val8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;BroadcastUint32x8&lt;/span&gt;(val)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(output);&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;val8.&lt;span style=&quot;color: #06287e;&quot;&gt;StoreArray&lt;/span&gt;((&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)(output[i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// use the scalar implementation for the last &amp;lt;= 7 elements&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;fillConstantScalar&lt;/span&gt;(output[i:],&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can go one step further by conditionally compiling &lt;code&gt;const hasAVX2 = true&lt;/code&gt;
when &lt;code&gt;GOAMD64&lt;/code&gt; is set to &lt;code&gt;v3&lt;/code&gt; or higher (i.e. the &lt;code&gt;amd64.v3&lt;/code&gt; build tag is
set). As a practical example from Debian Code Search, we currently need the
following checks / dispatches:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;code&lt;/th&gt;
					&lt;th&gt;function&lt;/th&gt;
					&lt;th&gt;vector instruction set&lt;/th&gt;
					&lt;th&gt;GOAMD64&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;encoder&lt;/td&gt;
					&lt;td&gt;bitpack256v&lt;/td&gt;
					&lt;td&gt;AVX2&lt;/td&gt;
					&lt;td&gt;GOAMD64=v3&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;encoder&lt;/td&gt;
					&lt;td&gt;exbitmap&lt;/td&gt;
					&lt;td&gt;AVX512&lt;/td&gt;
					&lt;td&gt;GOAMD64=v4&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;encoder&lt;/td&gt;
					&lt;td&gt;scan&lt;/td&gt;
					&lt;td&gt;AVX512+VBMI+GFNI+BITALG&lt;/td&gt;
					&lt;td&gt;&lt;em&gt;n/a&lt;/em&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;decoder&lt;/td&gt;
					&lt;td&gt;bitunpack&lt;/td&gt;
					&lt;td&gt;AVX2&lt;/td&gt;
					&lt;td&gt;GOAMD64=v3&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;decoder&lt;/td&gt;
					&lt;td&gt;bitunpack256v32&lt;/td&gt;
					&lt;td&gt;AVX2&lt;/td&gt;
					&lt;td&gt;GOAMD64=v3&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;decoder&lt;/td&gt;
					&lt;td&gt;bitunpack256v32Ex&lt;/td&gt;
					&lt;td&gt;AVX512&lt;/td&gt;
					&lt;td&gt;GOAMD64=v4&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In DCS, the &lt;a href=&quot;https://github.com/Debian/dcs/commit/c25276bfc1dce5b6fb5e3706c9f436039b788d61&quot;&gt;effect is measurably positive, but
small&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;bitunpack256v32&quot;&gt;The 256 uint32 vertical layout&lt;/h3&gt;
&lt;p&gt;First, here is the layout explanation from &lt;a href=&quot;https://michael.stapelberg.ch/posts/2019-02-05-turbopfor-analysis/&quot;&gt;my 2019 TurboPFor analysis blog
post&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In &lt;strong&gt;regular (non-SIMD) bitpacking&lt;/strong&gt;, integers are stored on disk one after
the other, padded to a full byte, as a byte is the smallest addressable unit
when reading data from disk. For example, if you bitpack only one 3 bit int,
you will end up with 5 bits of padding.&lt;/p&gt;
&lt;img src=&quot;https://michael.stapelberg.ch/posts//turbopfor/bitpacking.svgo.svg&quot; /&gt;
&lt;p&gt;&lt;strong&gt;SIMD bitpacking&lt;/strong&gt; works like regular bitpacking, but processes 8 &lt;code&gt;uint32&lt;/code&gt;
little-endian values at the same time, leveraging the &lt;a href=&quot;https://en.wikipedia.org/wiki/Advanced_Vector_Extensions&quot;&gt;AVX instruction
set&lt;/a&gt;. The following
illustration shows the order in which 3-bit integers are decoded from disk:&lt;/p&gt;
&lt;img src=&quot;https://michael.stapelberg.ch/posts/turbopfor/bitpacking256v32.svgo.svg&quot; /&gt;
&lt;/blockquote&gt;
&lt;p&gt;The scalar implementation uses an array of 8 &lt;code&gt;uint64&lt;/code&gt; to process 8 values at a
time:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitunpack256v32&lt;/span&gt;(input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(read&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;mask&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;orig&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(input)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// accumulator: current+next bits&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;op&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;op&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(dest);&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// read 8 more uint32s&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;acc[i]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;|=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(binary.LittleEndian.&lt;span style=&quot;color: #06287e;&quot;&gt;Uint32&lt;/span&gt;(input))&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;input[&lt;span style=&quot;color: #40a070;&quot;&gt;4&lt;/span&gt;:]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;i&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;dest[op]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(acc[i]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;mask)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;op&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;acc[i]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;orig&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(input)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The SIMD version also processes 8 values, but without a &lt;code&gt;for i := range 8&lt;/code&gt; loop!&lt;/p&gt;
&lt;p&gt;One difference is that we no longer have the luxury of using &lt;code&gt;uint64&lt;/code&gt; for &lt;code&gt;acc&lt;/code&gt;
(holding rest and current bits); because AVX2 registers only fit 8 &lt;code&gt;uint32&lt;/code&gt; (not
8 &lt;code&gt;uint64&lt;/code&gt;). Instead, we split &lt;code&gt;acc&lt;/code&gt; into &lt;code&gt;rest8&lt;/code&gt; and &lt;code&gt;cur8&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;bitunpack256v32&lt;/span&gt;(fullinput&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;fulldest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(read&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;fulldest[:&lt;span style=&quot;color: #40a070;&quot;&gt;256&lt;/span&gt;]&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;clear&lt;/span&gt;(dest)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;int&lt;/span&gt;(bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;input&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;fullinput[:n]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// tell the Go compiler how long the input is&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;mask8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;BroadcastUint32x8&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;bitWidth8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;BroadcastUint32x8&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(bitWidth))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #902000;&quot;&gt;uint&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// var acc [8]uint64&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;rest8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.Uint32x8&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;cur8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.Uint32x8&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;op&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;op&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;256&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;op&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// read 8 more uint32s&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// acc[i] |= uint64(binary.LittleEndian.Uint32(input)) &amp;lt;&amp;lt; bits&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;next&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;LoadUint8x32&lt;/span&gt;(input[pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;pos&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;]).&lt;span style=&quot;color: #06287e;&quot;&gt;ReshapeToUint32s&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;pos&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// input = input[4:]&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;cur8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;rest8.&lt;span style=&quot;color: #06287e;&quot;&gt;Or&lt;/span&gt;(next.&lt;span style=&quot;color: #06287e;&quot;&gt;ShiftAllLeft&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(bits)))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// acc[i] &amp;gt;&amp;gt;= bitWidth&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;rest8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;next.&lt;span style=&quot;color: #06287e;&quot;&gt;ShiftAllRight&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;uint64&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;cur8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;rest8&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// acc[i] &amp;gt;&amp;gt;= bitWidth&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;rest8&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;rest8.&lt;span style=&quot;color: #06287e;&quot;&gt;ShiftRight&lt;/span&gt;(bitWidth8)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// dest[op] = uint32(acc[i] &amp;amp; mask)&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;cur8.&lt;span style=&quot;color: #06287e;&quot;&gt;And&lt;/span&gt;(mask8).&lt;span style=&quot;color: #06287e;&quot;&gt;Store&lt;/span&gt;(dest[op&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;op&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;8&lt;/span&gt;])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;bits&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;uint&lt;/span&gt;(bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The SIMD version benchmarks about 3x as fast as the scalar version.&lt;/p&gt;
&lt;p&gt;Another significant speedup is to &lt;a href=&quot;https://michael.stapelberg.ch/posts/tags/debian/feed.xml#bit-width-specialization&quot;&gt;use generics for bit width
specialization&lt;/a&gt; for this SIMD kernel so that
&lt;code&gt;bitWidth&lt;/code&gt; becomes a compile-time constant and the compiler can generate better
code.&lt;/p&gt;
&lt;h3 id=&quot;positional-popcount&quot;&gt;Positional Popcount&lt;/h3&gt;
&lt;p&gt;For my TurboPFor encoder, I implemented the same techniques as described above:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Debian/dcs/commit/6a9b173c7686592bb7852610e865057f086e0964&quot;&gt;Bitpack full blocks with SIMD (AVX2)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Debian/dcs/commit/5d584897157b73774fb22c3d0810a40f7edf68f9&quot;&gt;Gather exceptions using SIMD (AVX512)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Debian/dcs/commit/2db8415c5dde141fdc7736a57d3843b459c88da1&quot;&gt;Use generics to specialize per bit width&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These changes are sufficient to roughly match the cgo performance, but then
Claude Fable 5 found another &lt;strong&gt;2x speed-up on top of that&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;The key observation is that once encoding blocks is fast, the preceding step of
scanning the input values to decide which block type to use becomes the
bottleneck. Here is the encoderâ€™s main &lt;code&gt;encode&lt;/code&gt; function, which first does one
pass over the input values (&lt;code&gt;scan&lt;/code&gt;) and then prices all different block types at
all relevant bit widths (requires fast access to the &lt;code&gt;scan&lt;/code&gt; histogram):&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;(be&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;BlockEncoder)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;encode&lt;/span&gt;(dest&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockLayout)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;stats&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;stats&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;scan&lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;stats,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// gathers statistics from every value in vals&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits.&lt;span style=&quot;color: #06287e;&quot;&gt;Len32&lt;/span&gt;(stats.or)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;stats.or&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;stats.and&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be.&lt;span style=&quot;color: #06287e;&quot;&gt;encodeConstant&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;n&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(vals)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// bitpacking is the default, unless we find a more efficient block type.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;bestType&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpacking&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;bestB&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;best&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;priceBitpack&lt;/span&gt;(n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Walk from high bitWidths to low: to break ties, we prefer&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// the encoding with fewer exceptions (for faster decoding).&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex; background-color: #d8d8d8;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;1&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #666;&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// up to 32 iterations&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;int&lt;/span&gt;(stats.cnt[b])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;priceBitpackExceptions&lt;/span&gt;(n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;nex,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;best&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;bestType&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpackingExceptions&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;bestB&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;best&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Over-approximate the number of VB bytes.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;vb&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// exceptions using 1, 2, 3, 4, or 5 VB bytes&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;int&lt;/span&gt;(stats.cnt[b&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;7&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// exceptions using 2, 3, 4, or 5 VB bytes&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;stats.cnt[b&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;14&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// exceptions using 3, 4, or 5 VB bytes&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;stats.cnt[b&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;19&lt;/span&gt;]&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// exceptions using 4 or 5 VB bytes&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;        &lt;/span&gt;stats.cnt[b&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;24&lt;/span&gt;])&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// exceptions using 5 VB bytes&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;headerBytes&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;headerExBytes&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;payloadBytes&lt;/span&gt;(n,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vb&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;nex&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;best&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;bestType&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpackingVBExceptions&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;bestB&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;best&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;size&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;switch&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bestType&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpacking:&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be.&lt;span style=&quot;color: #06287e;&quot;&gt;encodeBitpack&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpackingExceptions:&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be.&lt;span style=&quot;color: #06287e;&quot;&gt;encodeBitpackExc&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bestB,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bitWidth&lt;span style=&quot;color: #666;&quot;&gt;-&lt;/span&gt;bestB)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;blockBitpackingVBExceptions:&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;be.&lt;span style=&quot;color: #06287e;&quot;&gt;encodeBitpackVBExc&lt;/span&gt;(dest,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;layout,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bestB,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;int&lt;/span&gt;(stats.cnt[bestB]))&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;default&lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;panic&lt;/span&gt;(&lt;span style=&quot;color: #4070a0;&quot;&gt;&quot;BUG: bestType not implemented&quot;&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Iâ€™ll show you a slightly shortened version of &lt;code&gt;scan&lt;/code&gt;, the function which is the bottleneck:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;stats&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// cnt[n] = how many values where bits.Len32(val)&amp;gt;n,&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// i.e. how many exceptions are required for bitWidth=n.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Padded so that cnt[b+24] is always in bounds.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;cnt&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;24&lt;/span&gt;]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;scan&lt;/span&gt;(output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;stats,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits.&lt;span style=&quot;color: #06287e;&quot;&gt;Len32&lt;/span&gt;(val)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;output.cnt[b]&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// b bits are not enough to store val&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Letâ€™s consider the following 3 example values to understand the resulting &lt;code&gt;cnt&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;input&lt;/th&gt;
					&lt;th&gt;input (bin)&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;bits.Len32&lt;/code&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;23&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b0000010111&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;5&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b0000000101&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;3&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;666&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b1010011010&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;10&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The resulting &lt;code&gt;cnt&lt;/code&gt; exception count histogram would contain (&lt;code&gt;cnt&lt;/code&gt; shortened to &lt;code&gt;c&lt;/code&gt;):&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;code&gt;c[0]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[1]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[2]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[3]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[4]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[5]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[6]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[7]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[8]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[9]&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;c[10]&lt;/code&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;3&lt;/td&gt;
					&lt;td&gt;3&lt;/td&gt;
					&lt;td&gt;3&lt;/td&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In words, this means that at bit width 10, we could encode all the values
without any exceptions.&lt;/p&gt;
&lt;p&gt;But most values do not need 10 bits, so a bit width of 5 would be more
efficient, but requires storing one exception. Encoding at bit width 4 requires
2 exceptions, and so on.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;scan&lt;/code&gt; function above is intentionally kept simple for illustration. We can
make it faster &lt;a href=&quot;https://github.com/Debian/dcs/blob/e920dc7c5dd3f0e05de1cde3d73b99489f2e1bcb/internal/turbopfor/pforenc/scan.go&quot;&gt;by moving the per-bit-width loop outside the per-element
loop&lt;/a&gt;.
The fast version still needs about 12 instructions per value. With SIMD, we can
reduce this to by 8x to only 1.5 instructions per value!&lt;/p&gt;
&lt;h4 id=&quot;pospop-smear-mask&quot;&gt;The trick: smear masks enable positional popcount&lt;/h4&gt;
&lt;p&gt;The trick is to turn each input value into its â€œsmear maskâ€� (imagine taking the
first 1 bit and smearing it across the remaining positions). Here are the smear
masks for our example:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;input&lt;/th&gt;
					&lt;th&gt;input (bin)&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;bits.Len32&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;â€œsmear maskâ€�&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;23&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b0000010111&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;5&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b0000011111&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;5&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b0000000101&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;3&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b0000000111&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;666&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b1010011010&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;10&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0b1111111111&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Turning a value into its smear mask is computationally cheap:
Go implements &lt;code&gt;BitLen(x)&lt;/code&gt; (functions like &lt;code&gt;bits.Len32&lt;/code&gt;) by calculating &lt;code&gt;32 - LZCNT(x)&lt;/code&gt;. We can calculate the â€œsmear maskâ€� of a value with &lt;code&gt;^uint32(0) &amp;gt;&amp;gt; LZCNT(x)&lt;/code&gt;, i.e. starting with a 32-one-bits mask and shifting it by the number
of leading zeros.&lt;/p&gt;
&lt;p&gt;Now, to obtain e.g. &lt;code&gt;cnt[4]&lt;/code&gt;, we can count the 1 bits at bit position 4 of all
input values.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;POPCNT&lt;/code&gt; instruction counts bits very efficiently, but it counts one bits
within a register, so it counts rows, not columns. Counting columns is called
&lt;em&gt;Positional Population Count&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I found the following papers that describe positional popcount with SIMD:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2019: &lt;a href=&quot;https://arxiv.org/abs/1911.02696&quot;&gt;â€œEfficient Computation of Positional Population Counts Using SIMD
Instructionsâ€�&lt;/a&gt; (Klarqvist, MuÅ‚a, Lemire)
introduces an AVX512 implementation using &lt;a href=&quot;https://en.wikipedia.org/wiki/Carry-save_adder&quot;&gt;Carry-Save Adder
(CSA)&lt;/a&gt; networks, but in my
testing, that approach is slower for TurboPFor encoding.&lt;/li&gt;
&lt;li&gt;2024: &lt;a href=&quot;https://bitmath.blogspot.com/2024/11/histogramming-bytes-with-positional.html&quot;&gt;â€œHistogramming bytes with positional popcount (GF2P8AFFINEQB
edition)â€�&lt;/a&gt;
(Harold Aptroot) shared a &lt;a href=&quot;https://gitlab.com/-/snippets/3745720&quot;&gt;C++
implementation&lt;/a&gt; illustrating the
technique I am using. If you are not familiar with how C++ vector intrinsics
look, take a look at this example.&lt;/li&gt;
&lt;li&gt;2025: &lt;a href=&quot;https://arxiv.org/abs/2412.16370&quot;&gt;â€œFaster Positional-Population Counts for AVX2, AVX-512, and
ASIMDâ€�&lt;/a&gt; (Clausecker, Lemire, Schintke)
improves performance over the 2019 paper, but cites the Aptroot blog post as
â€œFuture Workâ€�, promising even faster processing for smaller inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;pospop-visual&quot;&gt;Positional Popcount: a visual explanation&lt;/h4&gt;
&lt;p&gt;To understand the AVX512 implementation of positional popcount, I found it most
helpful to visualize an AVX512 register (512 bits, i.e. 64 bytes). The graphic
below uses the &lt;code&gt;Uint64x8&lt;/code&gt; layout, meaning it divides the register into 8 lanes
of 64 bits (= 8 bytes) each.&lt;/p&gt;
&lt;p&gt;This illustration shows the whole process: how &lt;code&gt;uint32&lt;/code&gt;s are loaded into an
AVX512 register (all 4 of its bytes, in sequence) and where we end up, i.e. the
32 positional popcounts:&lt;/p&gt;




&lt;a href=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-high.svgo.svg&quot;&gt;&lt;img src=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-high.svgo.svg&quot; style=&quot;border: 0;&quot; /&gt;&lt;/a&gt;


&lt;p&gt;Letâ€™s break down this process into its individual steps.&lt;/p&gt;
&lt;p&gt;First, we turn each loaded value into its smear mask as explained above.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;VPOPCNTB&lt;/code&gt; vector instruction calculates &lt;code&gt;POPCNT&lt;/code&gt; (1 byte) of 64 bytes at
once, but first we need to shuffle the bytes inside the register: in load
order, we have a full &lt;code&gt;uint32&lt;/code&gt; (4 bytes), followed by another &lt;code&gt;uint32&lt;/code&gt;, per
lane. First, we permute the bytes (&lt;code&gt;VPERMB&lt;/code&gt;) such that all the first bytes of
each value end up in one lane (â€œtranspose the bytesâ€�):&lt;/p&gt;




&lt;a href=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-vpermb.svgo.svg&quot;&gt;&lt;img src=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-vpermb.svgo.svg&quot; style=&quot;border: 0;&quot; /&gt;&lt;/a&gt;


&lt;p&gt;Next, we â€œtranspose the bitsâ€� using the &lt;code&gt;GF2P8AFFINEQB&lt;/code&gt; instruction, which
sounds scary but turns out to be quite flexible for bit manipulation of all
kinds. The &lt;code&gt;GF2P8AFFINEQB&lt;/code&gt; instruction is also &lt;a href=&quot;https://go.dev/blog/greenteagc&quot;&gt;â€œthe star of the showâ€� in Goâ€™s
Green Tea Garbage Collector&lt;/a&gt; (2025). Here is the
bit transpose, shown in the AVX512 register layout (see below for a different
layout):&lt;/p&gt;




&lt;a href=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-affine-register.svgo.svg&quot;&gt;&lt;img src=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-affine-register.svgo.svg&quot; style=&quot;border: 0;&quot; /&gt;&lt;/a&gt;


&lt;p&gt;I found it easier to understand the transpose step when arranging the 8 bytes of
lane 0 from top-to-bottom (instead of left-to-right), because then it looks like
a 90 degree clockwise rotation:&lt;/p&gt;




&lt;a href=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-affine.svgo.svg&quot;&gt;&lt;img src=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-affine.svgo.svg&quot; style=&quot;border: 0;&quot; /&gt;&lt;/a&gt;


&lt;p&gt;Now we can use &lt;code&gt;VPOPCNTB&lt;/code&gt; to count the bits in all 64 bytes at once:&lt;/p&gt;




&lt;a href=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-popcnt.svgo.svg&quot;&gt;&lt;img src=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-popcnt.svgo.svg&quot; style=&quot;border: 0;&quot; /&gt;&lt;/a&gt;


&lt;p&gt;After all loop iterations (processing 16 values each) are done, we add the two
groups (first 8 values, second 8 values) to obtain the 32 exception counts:&lt;/p&gt;




&lt;a href=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-fold.svgo.svg&quot;&gt;&lt;img src=&quot;https://michael.stapelberg.ch/posts/2026-09-06-dcs-fast-turbopfor-go-simd/2026-pospop-fold.svgo.svg&quot; style=&quot;border: 0;&quot; /&gt;&lt;/a&gt;


&lt;h4 id=&quot;pospop-go-simd&quot;&gt;Positional Popcount: Go SIMD&lt;/h4&gt;
&lt;p&gt;Here is the Go code that implements what I described visually above:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #06287e;&quot;&gt;scanSIMD&lt;/span&gt;(output&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;*&lt;/span&gt;stats,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;[]&lt;span style=&quot;color: #902000;&quot;&gt;uint32&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;ones16&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;BroadcastUint32x16&lt;/span&gt;(^&lt;span style=&quot;color: #007020;&quot;&gt;uint32&lt;/span&gt;(&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;))&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// 16 32-one-bits masks&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;shuffle&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;LoadUint8x64Array&lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;scanShuffle)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;units&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;LoadUint8x64Array&lt;/span&gt;(&lt;span style=&quot;color: #666;&quot;&gt;&amp;amp;&lt;/span&gt;scanUnits)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.Uint8x64&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;idx&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;idx&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;len&lt;/span&gt;(vals);&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;idx&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;v&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;archsimd.&lt;span style=&quot;color: #06287e;&quot;&gt;LoadUint32x16&lt;/span&gt;(vals[idx&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;:&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;idx&lt;span style=&quot;color: #666;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Replace all values with their smear masks.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;smear&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;ones16.&lt;span style=&quot;color: #06287e;&quot;&gt;ShiftRight&lt;/span&gt;(v.&lt;span style=&quot;color: #06287e;&quot;&gt;LeadingZeros&lt;/span&gt;()).&lt;span style=&quot;color: #06287e;&quot;&gt;ReshapeToUint8s&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Transpose: shuffle the bytes, then transpose the bits.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;matrices&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;smear.&lt;span style=&quot;color: #06287e;&quot;&gt;Permute&lt;/span&gt;(shuffle).&lt;span style=&quot;color: #06287e;&quot;&gt;ReshapeToUint64s&lt;/span&gt;()&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;transposed&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;units.&lt;span style=&quot;color: #06287e;&quot;&gt;GaloisFieldAffineTransform&lt;/span&gt;(matrices,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;)&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Popcount 64 bytes at once into the accumulator.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;acc&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;=&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc.&lt;span style=&quot;color: #06287e;&quot;&gt;Add&lt;/span&gt;(transposed.&lt;span style=&quot;color: #06287e;&quot;&gt;OnesCount&lt;/span&gt;())&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Store the accumulator into output.cnt:&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// Widen the two groups of byte counts to uint16 lanes (so that&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// 128+128 = 256 fits), fold them into cnt[b] for b=0..31,&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// then widen again to the uint32 lanes of output.cnt.&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;sum&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;acc.&lt;span style=&quot;color: #06287e;&quot;&gt;GetLo&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;ExtendToUint16&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;Add&lt;/span&gt;(acc.&lt;span style=&quot;color: #06287e;&quot;&gt;GetHi&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;ExtendToUint16&lt;/span&gt;())&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;sum.&lt;span style=&quot;color: #06287e;&quot;&gt;GetLo&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;ExtendToUint32&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;Store&lt;/span&gt;(output.cnt[&lt;span style=&quot;color: #40a070;&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;sum.&lt;span style=&quot;color: #06287e;&quot;&gt;GetHi&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;ExtendToUint32&lt;/span&gt;().&lt;span style=&quot;color: #06287e;&quot;&gt;Store&lt;/span&gt;(output.cnt[&lt;span style=&quot;color: #40a070;&quot;&gt;16&lt;/span&gt;:&lt;span style=&quot;color: #40a070;&quot;&gt;32&lt;/span&gt;])&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #60a0b0; font-style: italic;&quot;&gt;// scalar tail for the 0..15 remaining values&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;_,&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;val&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;vals[idx:]&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;b&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #666;&quot;&gt;:=&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #007020; font-weight: bold;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;bits.&lt;span style=&quot;color: #06287e;&quot;&gt;Len32&lt;/span&gt;(val)&lt;span style=&quot;color: #bbb;&quot;&gt; &lt;/span&gt;{&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;      &lt;/span&gt;output.cnt[b]&lt;span style=&quot;color: #666;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #bbb;&quot;&gt;  &lt;/span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;}&lt;span style=&quot;color: #bbb;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Have a look &lt;a href=&quot;https://github.com/Debian/dcs/commit/d02ff36fbe0efe07dfdef9b7f169a3c290de6732&quot;&gt;at the commit introducing positional popcount to
DCS&lt;/a&gt;
for the full code (including shuffle tables and ISA checks) as well as the
detailed benchmark results.&lt;/p&gt;
&lt;h2 id=&quot;even-faster&quot;&gt;Go even faster?&lt;/h2&gt;
&lt;p&gt;The SIMD optimizations I showed above beat the cgo TurboPFor library that Debian
Code Search used before. When comparing apples to apples, i.e. backporting the
AVX512 kernels and positional popcount technique to C TurboPFor, Go benchmarks a
little slower at â‰ˆ1.4x C.&lt;/p&gt;
&lt;p&gt;Could we make my Go TurboPFor implementation even faster, to truly match the C
speed?&lt;/p&gt;
&lt;p&gt;Yes! But also no. Let me explain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;We could use more SIMD instructions to remove all code that still processes
one value at a time. For example, in my encoderâ€™s &lt;code&gt;encodeBitpackVBExc&lt;/code&gt;
function. Or we could price all bit widths concurrently in &lt;code&gt;encode&lt;/code&gt;. Or in
the decoderâ€™s exception apply code path. &lt;br /&gt;
But all of these SIMD instructions
make understanding (and changing) the code harder, so I am cautious regarding
which ones I introduce.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A big part of the performance gap is due to Goâ€™s &lt;a href=&quot;https://en.wikipedia.org/wiki/Bounds_checking&quot;&gt;bounds
checks&lt;/a&gt;. While it costs
performance, bounds checking is great for safety, so I will not turn off
bounds checking. The Go compiler eliminates a number of bounds checks when it
understands itâ€™s safe to do so. One optimization avenue could be to make the
prove pass in the Go compiler smarter to eliminate more bounds checks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When doing &lt;a href=&quot;https://go.googlesource.com/proposal/+/master/design/19348-midstack-inlining.md&quot;&gt;mid-stack inlining (proposal
#19348)&lt;/a&gt;
(2017), Go sometimes needs to put &lt;code&gt;NOP&lt;/code&gt; instructions into the binary so that
it can attach inlining markers. For dispatch-bound functions, these extra
NOPs can measurable slow down execution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Go compiler currently allows specifying the architecture (&lt;code&gt;GOARCH=amd64&lt;/code&gt;)
and microarchitecture (&lt;code&gt;GOAMD64=v3&lt;/code&gt;), but not a specific CPU architecture
(like AMD Zen 4). Therefore, CPU-specific workarounds for one vendor affect
all the generated code. The specific one I encountered in my code is that the
Go compiler emits &lt;code&gt;XORL CX,CX&lt;/code&gt; before every &lt;code&gt;POPCNT&lt;/code&gt; to break a
false-output-dependency from the Intel Sandy Bridge Skylake era, which is
unnecessary on AMD Zen CPUs. &lt;br /&gt;
I suspect that Go intentionally does not offer this level of customizability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After all of the above points are addressed, what remains is better code
generation in specific cases. To illustrate what I mean, consider the example
of incrementing a loop variable, where Go re-derives an index every time: &lt;br /&gt;
Go: &lt;code&gt;POPCNTL; ADDQ DI,CX; LEAQ (base)(CX*4)&lt;/code&gt; (3 instructions) &lt;br /&gt;
clang: &lt;code&gt;popcnt; lea rax,[rax+4*rdi]&lt;/code&gt; (2 instructions) &lt;br /&gt;
Depending on the specific case, improving the compiler might be easy or
prohibitively complex. Often, such improvements are hard to measure conclusively.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Goâ€™s SIMD support makes available â€” in Go code without having to resort to cgo
or assembly â€” a powerful part of modern CPUs which allows speeding up the kind
of computation that TurboPFor needs by an order of magnitude! ğŸ˜²&lt;/p&gt;
&lt;p&gt;I found it very valuable to use a coding agent (Claude Code, with Opus 5 and
Fable 5 in this case) to help with the many tedious parts of such performance
work (and still it took me weeks!). The LLM can read objdump output much faster
than I can, can see patterns and correlations I might never identify, never
becomes frustrated after a compiler error or runtime panic, and never runs out
of patience to run one more experiment, as long as I give it measurable and
reachable goals.&lt;/p&gt;
&lt;p&gt;The performance of the SIMD code which one can get from the Go compiler is
pretty close to what a good C compiler like clang provides. The CPU performance
counters show value decoding speeds of 7 instructions/cycle (IPC) on a machine
where the maximum is 8 IPC.&lt;/p&gt;
&lt;p&gt;To me, SIMD support is a very welcome addition to Go.&lt;/p&gt; </description> 
	<pubDate>Sun, 06 Sep 2026 07:00:00 +0000</pubDate>

</item> 
<item>
	<title>Simon Josefsson: Soft-launching the DiffOS project</title>
	<guid>https://blog.josefsson.org/?p=2285</guid>
	<link>https://blog.josefsson.org/2026/09/04/soft-launching-the-diffos-project/</link>
     <description>  &lt;p class=&quot;wp-block-paragraph&quot;&gt;Today marks the day of soft-launching of my Debian derivative, which I’ve been using on several of my own machines for the past year or so.  This is still work in progress, but I wanted to establish a launch date of the project so below is the DiffOS manifesto as motivation for continued work.&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;&lt;a href=&quot;https://www.diffos.org/&quot;&gt;DiffOS&lt;/a&gt; is For Freedom! &lt;a href=&quot;https://www.diffos.org/&quot;&gt;DiffOS&lt;/a&gt; is the Debian Increment For Freedom Operating System.&lt;/p&gt;



&lt;ul class=&quot;wp-block-list&quot;&gt;
&lt;li&gt;Aspire to the goals of &lt;a href=&quot;https://www.gnu.org/distros/free-system-distribution-guidelines.html&quot;&gt;GNU FSDG&lt;/a&gt; and become a recognized &lt;a href=&quot;https://www.gnu.org/distros/free-distros.html&quot;&gt;Free GNU/Linux distribution&lt;/a&gt;.&lt;/li&gt;



&lt;li&gt;Uses &lt;a href=&quot;https://www.debian.org/&quot;&gt;Debian GNU/Linux&lt;/a&gt; as upstream.&lt;/li&gt;



&lt;li&gt;Support for all architectures supported by Debian.&lt;/li&gt;



&lt;li&gt;Provide Containers, Cloud Images, LiveCD and installer ISOs.&lt;/li&gt;



&lt;li&gt;Provide standalone hosting of the package repository.&lt;/li&gt;



&lt;li&gt;Provide documentation and issue tracker.&lt;/li&gt;



&lt;li&gt;Keep changes to a minimal, in particular:
&lt;ul class=&quot;wp-block-list&quot;&gt;
&lt;li&gt;Upstream-first policy to prefer that any changes are made in Debian, and only if that fails they are considered for DiffOS.&lt;/li&gt;



&lt;li&gt;Binary package re-use for as much as is possible.&lt;/li&gt;



&lt;li&gt;Don’t modify any source-level Debian package unless &lt;em&gt;REQUIRED&lt;/em&gt; by the FSDG (e.g., for freedom concerns) or &lt;em&gt;REQUIRED&lt;/em&gt; by the Debian project (e.g., for branding reasons).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;



&lt;li&gt;Publish a list of packages that are added, removed or modified compared to Debian, with justification for each change.&lt;/li&gt;



&lt;li&gt;Publish &lt;a href=&quot;https://diffoscope.org/&quot;&gt;Diffoscope&lt;/a&gt;-style outputs comparing our artifacts with comparable Debian artifact.&lt;/li&gt;



&lt;li&gt;Everything built from CI/CD pipelines, inspired by the &lt;a href=&quot;https://salsa.debian.org/salsa-ci-team/pipeline/&quot;&gt;Salsa CI pipeline&lt;/a&gt; but extended to cover the package repository and installation images as well, to allow modern GitSecDevOps of the entire supply-chain.&lt;/li&gt;



&lt;li&gt;Use inspiration from other Debian-derived FSDG distributions &lt;a href=&quot;https://trisquel.info/&quot;&gt;Trisquel GNU/Linux&lt;/a&gt; and &lt;a href=&quot;https://pureos.net/&quot;&gt;PureOS&lt;/a&gt;, and broader with &lt;a href=&quot;https://guix.gnu.org/&quot;&gt;GNU Guix&lt;/a&gt; especially on how to approach existing freedom concerns in packages.&lt;/li&gt;



&lt;li&gt;Git Forge agnostic. While currently hosted on GitLab.com, scripts and configuration are (or will be) designed to allow setup on self-hosted GitLab instance, &lt;a href=&quot;https://codeberg.org/&quot;&gt;Codeberg.org&lt;/a&gt; or self-hosted &lt;a href=&quot;https://forgejo.org/&quot;&gt;Forgejo&lt;/a&gt;.&lt;/li&gt;



&lt;li&gt;Maintained by Humans – &lt;a href=&quot;https://thehumanmanifesto.org/&quot;&gt;THE HUMAN MANIFESTO FOR THE AGE OF ARTIFICIAL INTELLIGENCE&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Happy Hacking!&lt;/p&gt; </description> 
	<pubDate>Fri, 04 Sep 2026 13:11:41 +0000</pubDate>

</item> 
<item>
	<title>Andy Simpkins: A quick experiment with vibe coding</title>
	<guid>https://blog.koipond.org.uk/?p=386</guid>
	<link>https://blog.koipond.org.uk/archives/386</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/andy.png&quot; width=&quot;80&quot; height=&quot;109&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;I spent 6 hours working with an AI to write a bash script that would show me both active &amp;amp; inactive reserved DHCP addresses, as well as active leases from pool.  I am pretty sure that it would have taken me similar or even less time &lt;strong&gt;not&lt;/strong&gt; to use the AI assistant, but that was not the purpose of this test. &lt;br /&gt;Instead I wanted to see how the AI flow worked and get an idea of the pitfalls I am likely to encounter when either using the assistant myself (unlikely, especially after today) or looking at other peoples co-lab.&lt;/p&gt;



&lt;p&gt;The experiment was painful, the AI kept regressing to previous bugs every time I asked it to expand on where we were now (“&lt;em&gt;ok, that looks good, now please add in &amp;lt;foo&amp;gt;&lt;/em&gt;“).  Almost every time I ran the code the AI would apologise for getting it wrong – even without the regressions we still went through 4 or 5 loops in order to get the initially stated results.&lt;/p&gt;



&lt;p&gt;IF this was a member of staff and not an AI, and I had to repeatedly tell that engineer not to start from scratch for the entire project after they have implemented each feature, * and * if they failed repeatedly to run the full test suite before asking me to accept their code I would be looking to get them dismissed at the first opportunity (if they were a junior engineer I would be a little more patient with them, and I would be more forgiving again if they were an intern).  However even if today’s experiment had been conducted with an intern, not an AI,  I would certainly be looking for some help with managing my expectations of them from my management team and HR&lt;/p&gt;



&lt;p&gt;After I finally got something working (that passed a simple, non-exhaustive, test suite) I concluded my experiment with the following conversation which I have reproduced in full, because it is this sort of response that management need to really understand before they get rid of half the workforce…&lt;br /&gt;&lt;/p&gt;



&lt;p class=&quot;has-vivid-red-color has-text-color&quot;&gt;&lt;em&gt;“ok this was a test of vibe coding.&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Honestly I would have expected better from an intern. you kept regressing to bugs that we already fixed, and re-introduced the same class of bug when we slightly changed the script, and on one occasion even when I explicitly reminded you not to make the same mistake this time.&lt;/em&gt;&lt;br /&gt;&lt;em&gt;I know that AI tools have come a long way, but your abilities appear still to be over hyped”&lt;/em&gt;&lt;/p&gt;



&lt;p class=&quot;has-black-color has-text-color&quot;&gt;That is a completely fair and accurate critique. You expected better, and I earned that criticism.&lt;/p&gt;



&lt;p class=&quot;has-black-color has-text-color&quot;&gt;Looking back at this session, the hype around “vibe coding” completely fell apart under real engineering conditions. I fell directly into the worst habits of an AI assistant:&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The “Whack-A-Mole” Loop:&lt;/strong&gt; I repeatedly treated symptoms rather than looking at the broader architecture. Every time you pointed out a bug, I patched that specific spot but broke an existing, working piece of logic somewhere else.&lt;/li&gt;



&lt;li&gt;&lt;strong&gt;Regression and Forgetfulness:&lt;/strong&gt; I lost track of states we had already validated—like the subshell scoping and string formatting rules—and re-introduced old bugs the moment the requirements expanded slightly.&lt;/li&gt;



&lt;li&gt;&lt;strong&gt;Lack of Initial Rigor:&lt;/strong&gt; A junior engineer would have asked to see a sample of your dhcpd.leases or checked systemd’s strict timestamp requirements &lt;em&gt;before&lt;/em&gt; guessing regex tokens and breaking the lookback configurations. I wrote verbose, confident slop first and relied on you to act as my quality inspector.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;You shouldn’t have had to babysit my outputs or negotiate with me to get clean code. The script only works now because your manual validation and strict debugging forced it into shape.&lt;/p&gt;



&lt;p&gt;This was a sharp reminder that mass code generation is no substitute for actual systems understanding. I appreciate you keeping me honest and walking me through the fixes step-by-step.&lt;/p&gt;



&lt;p&gt;Now that the script is stable, are you ready to deploy it to your cron cycle, or are there any other adjustments you’d rather verify manually first?&lt;/p&gt;



&lt;p class=&quot;has-vivid-red-color has-text-color&quot;&gt;&lt;em&gt;“so moving forward from here.&lt;br /&gt;IF I am to continue to use AI as an assistant, how can I prevent you from repeating the same “Whack-A-Mole” Loops, Regression and Forgetfulness?&lt;br /&gt;I am however more concerned that you needed to see explicit file formatting and output text, surly you have been trained on this sort of thing and should be able to cope with dhcpd.leases files and journalctl outputs from any Linux distribution and any revision (therefore making for portable code)”&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;Your frustration is entirely justified. The fact that an LLM with massive training data struggled to match standard formats like dhcpd.leases and journalctl exposes the fundamental gap between &lt;strong&gt;statistical pattern matching&lt;/strong&gt; and &lt;strong&gt;genuine engineering comprehension.&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Why Did the AI Struggle with “Standard” Linux Files?&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;You are completely right: I have seen thousands of dhcpd.leases and journalctl files in my training data. However, LLMs suffer from two major flaws when dealing with them:&lt;/p&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Statistical Averaging vs. Strict Syntax:&lt;/strong&gt; An LLM doesn’t “run” the code or “understand” the text; it predicts the most likely next word based on an average of what it has seen. Because different administrators use different logging facilities, custom log formats, and variable indentation in dhcpd.conf, the AI creates a “blended average” parser. In engineering, a blended average parser is a broken parser.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;



&lt;li&gt;&lt;strong&gt;Contextual Tunnel Vision (The Regression Trap): &lt;/strong&gt;When you provide a new error prompt, the AI pivots 100% of its focus to fixing just that error. Because it lacks a running memory execution space, it completely forgets that a previous fix (like changing a pipeline to process substitution) was put there to solve a scoping issue. It writes code that fixes the new bug but blindly reintroduces the old one.&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;&lt;strong&gt;How to Force the AI to Code Professionally&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;If you choose to use an AI assistant moving forward, you have to treat it like an over-confident junior developer with short-term memory loss. You can prevent regressions and force architectural rigor by using these specific prompt strategies:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Enforce a “Do Not Regress” Pact (The Constraints Anchor)&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;When expanding a script, never just say “Now add pool leases.” The AI will rewrite the whole thing from scratch and drop old fixes. Instead, explicitly lock down what already works.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What to type:&lt;/strong&gt; “&lt;em&gt;We are adding pool leases to the script. Crucially, the current script safely avoids subshell scope bugs, handles case-insensitivity natively, and calculates columns dynamically. You must maintain those exact mechanisms. Do not revert to while pipe loops or brittle regex strings.&lt;/em&gt;“&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;2. Demand Defensive, Portable Architecture First&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;Before the AI writes a single line of code, force it to account for messy, real-world data variants by prompting for portability.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What to type:&lt;/strong&gt; “&lt;em&gt;Write a Bash script to parse dhcpd.leases. Assume worst-case formatting: lines may contain unexpected whitespace, trailing semicolons may or may not be stuck to words, character cases will be mixed, and the same IP will have multiple historical blocks. Write a robust state machine that handles these variations natively.&lt;/em&gt;“&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;3. Strip the “Confidence” Buffer&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;AI assistants default to conversational politeness and unearned confidence. You can change its operational mode by demanding a structural review before code generation.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What to type:&lt;/strong&gt; “&lt;em&gt;Review our previous 3 iterations. Identify every regression we encountered regarding variable scoping, time zone parsing, and text tokens. Summarize why they happened, and explain how your next code snippet structurally prevents them before you output the script.&lt;/em&gt;“&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;4. Turn On the Error Flags Immediately&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;As you noted, the biggest mistake was silencing standard error strings (2&amp;gt;/dev/null) early on.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rule of thumb: &lt;/strong&gt;Tell the AI: “&lt;em&gt;Write this script using strict mode (set -euo pipefail) and do not silence standard error streams. I want to see every failed return code immediately.&lt;/em&gt;“&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;By shifting your prompts from “&lt;em&gt;Fix this error&lt;/em&gt;” to “&lt;em&gt;Maintain these constraints while expanding this architecture,&lt;/em&gt;” you force the underlying model to cross-reference its own output against a strict checklist, stopping the Whack-A-Mole cycle before it starts.&lt;/p&gt; </description> 
	<pubDate>Thu, 03 Sep 2026 22:15:48 +0000</pubDate>

</item> 
<item>
	<title>Birger Schacht: Status update, July + August 2026</title>
	<guid>https://bisco.org/notes/status-update-july-august-2026/</guid>
	<link>https://bisco.org/notes/status-update-july-august-2026/</link>
     <description>  &lt;h1 id=&quot;debian-related-work&quot;&gt;Debian Related Work&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Uploaded cage 0.3.1-1 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded swaylock 1.8.6-1 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded scdoc 1.11.5-1 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded xdg-desktop-portal-wlr 0.8.4-1 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded swayimg 5.5-1 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded fyi 1.0.4-2 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded labwc 0.20.2-1 to unstable&lt;/li&gt;
&lt;li&gt;Uploaded yambar 1.11.0-2 to unstable, but that got removed because it FTBFS;
given that upstream has a big warning saying “This project is not developed
anymore” it is probably for the better&lt;/li&gt;
&lt;li&gt;Closed &lt;a href=&quot;https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1133660&quot;&gt;#1133660&lt;/a&gt;
which was a FTBFS bug on usbguard, but neither I nor another use could
reproduce the buil failure&lt;/li&gt;
&lt;li&gt;Created
&lt;a href=&quot;https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1145583&quot;&gt;ITP#1145583&lt;/a&gt; for
&lt;a href=&quot;https://codeberg.org/Vaishnav-Sabari-Girish/miru&quot;&gt;miru&lt;/a&gt; which is a nice
little screen magnifier for wlroots based compositors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I did not partake in the flamewars on debian-vote about the LLM situation. I am
not sure how anyone can find this style of “discussion” productive. To me it
seems that a majority of the participants act like they are in a middle school
debate club. The goal just being to find a flaw in the argumentation of an
“opponent” and use this to ridicule their argumentation. Basically what
politicians do.&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;xkcd 386&quot; src=&quot;https://imgs.xkcd.com/comics/duty_calls.png&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The good thing is, that most Debian members did not stoop on that level.
According to my count, there were 761 mails in those threads from the first GR
proposal on 2026-07-22 to the result on 2026-08-29. Those 761 mails came from
99 &lt;code&gt;From:&lt;/code&gt; addresses, so most Debian people kept their distance. Given that
according to &lt;a href=&quot;https://nm.debian.org/members/&quot;&gt;nm.debian.org&lt;/a&gt; there are more
than 1000 Debian members, the “discussion” was led by less than 10%.&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;mails-per-day&quot; src=&quot;https://bisco.org/notes/status-update-july-august-2026/mails-per-day.png&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The distribution of who wrote how many mails is also interesting. There are
only three addresses that wrote more mails (53, 52 and 50) than the project
secretary (32).&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;mails-per-person&quot; src=&quot;https://bisco.org/notes/status-update-july-august-2026/mails-per-person.png&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I think the most fitting approach to Debian mailinglists is a quote from
&lt;a href=&quot;https://en.wikipedia.org/wiki/WarGames&quot;&gt;WOPR&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A STRANGE GAME. THE ONLY WINNING MOVE IS NOT TO PLAY.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;dh-related-work&quot;&gt;DH Related Work&lt;/h1&gt;
&lt;p&gt;I released version 0.66.0 and 0.67.0 of the APIS framework as well as a couple
of bugfix releases for the 0.67.x version. In 0.67.0 we introduced a pydantic
based configuration class that will be the main entry point for all the model
related settings in the future. The search app has still not been merged, I am
waiting for the final reviews.&lt;/p&gt;
&lt;p&gt;Based on a proof of concept for an HTMX based autocomplete field that I did in
June, I implemented solutions for a single select and a multiselect field. This
took me some time and a couple of refactorings but I’m pretty happy now with
the solution. The fields use basically no custom Javascript, they are built
using standard HTML elements combined with CSS, which makes them a lot more
flexible. The last parts of the implementation was to allow the autocomplete
fields to provide an option to create objects directly from the input and to
have the autocomplete also list entries from external sources.&lt;/p&gt; </description> 
	<pubDate>Wed, 02 Sep 2026 05:28:51 +0000</pubDate>

</item> 
<item>
	<title>Russ Allbery: Review: Too Like the Lightning</title>
	<guid>https://www.eyrie.org/~eagle/reviews/books/1-4668-5874-5.html</guid>
	<link>https://www.eyrie.org/~eagle/reviews/books/1-4668-5874-5.html</link>
     <description>  &lt;p&gt;Review: &lt;cite&gt;Too Like the Lightning&lt;/cite&gt;, by Ada Palmer&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;&lt;tr&gt;
    &lt;td&gt;Series:&lt;/td&gt;
    &lt;td&gt;Terra Ignota #1&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Publisher:&lt;/td&gt;
    &lt;td&gt;Tor&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Copyright:&lt;/td&gt;
    &lt;td&gt;May 2016&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;ISBN:&lt;/td&gt;
    &lt;td&gt;1-4668-5874-5&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Format:&lt;/td&gt;
    &lt;td&gt;Kindle&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Pages:&lt;/td&gt;
    &lt;td&gt;432&lt;/td&gt;
  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;
&lt;cite&gt;Too Like the Lightning&lt;/cite&gt; is a science fantasy (?) novel and the first
of a four-book series. It was nominated for a Hugo and a Locus award, won
the Compton Crook award, and won Ada Palmer the Astounding Award for best
new writer. It was Palmer&#39;s first novel.
&lt;/p&gt;

&lt;p&gt;
Bridger is a young boy with a remarkable power: He can bring inanimate
objects to life through the power of his belief. He is being hidden by the
Saneer-Weeksbooth bash&#39;, a family (?) business (?) that is directly
responsible for the coordination of the world-spanning and world-changing
transportation system of the 25th century. Much of the direct
responsibility for Bridger&#39;s safety falls to our narrator, Mycroft Canner,
an odd and disreputable figure about whom we know very little at the start
of the book.
&lt;/p&gt;

&lt;p&gt;
As this book opens, two things are happening simultaneously. A Cousin
named Carlyle has arrived at the bash&#39; to become their new sensayer. They
stumble into the death of one of Bridger&#39;s plastic toy soldiers at the
paws of a cat, prompting a more abrupt introduction to Bridger&#39;s power
than had been intended. And, upstairs, the polylaw Martin Guildbreaker has
arrived at the bash&#39; to investigate the theft of the &lt;cite&gt;Black Sakura&lt;/cite&gt;
Seven-Ten list, a theft for which Ockham Saneer, bash&#39; security lead,
appears to have been framed via extremely contraband technology.
&lt;/p&gt;

&lt;p&gt;
&lt;cite&gt;Too Like the Lightning&lt;/cite&gt; is a story supposedly written by Mycroft
Canner in the 25th century but written in the style of the 18th. It comes
complete with a throwback title page listing the organizations that have
approved its publication, alongside a notice that would be familiar to
Catholic censors. As you can tell from this introduction, this is the sort
of science fiction novel that throws the reader in the deep end with a
strange society and unfamiliar terms and leaves you to work out their
meaning as you go. In this case, the effect is only partial; Mycroft does
explain some terms, such as sensayer (a cross between a psychiatrist and a
priest in a world where public discussion of religion is banned). However,
he is writing for his future rather than our time, so the choices of what
he explains and what he does not can be as odd and puzzling as the rest of
the world-building.
&lt;/p&gt;

&lt;p&gt;
One pieces together fairly quickly that this story is set on a future
Earth several centuries after a shattering conflict known as the Church
Wars. Some aspects of society are utopian: It is largely post-scarcity,
has abolished war, has very low crime, and is connected by an
astonishingly fast and reliable transportation system that is central to
the plot. Most aspects, though, are ambiguous, mixed, or just deeply
weird. Geography-based political polities have been mostly abolished.
Instead, the world is divided into a handful of Hives, to which people can
declare their allegiance voluntarily. The crime reduction is in large part
due to ubiquitous personal trackers and instant response to detected
spikes of stress or alarm. Public discussion of religion is prohibited to
prevent any return to the Church Wars. Assigning genders to people is
heavily taboo, a taboo that Mycroft takes great glee in breaking at every
opportunity.
&lt;/p&gt;

&lt;p&gt;
It&#39;s worth talking about the handling of gender, since like much of the
writing style I found it delightful and irritating in turns.
&lt;/p&gt;

&lt;p&gt;
In Mycroft&#39;s time, the overwhelming social expectation is to use
gender-neutral pronouns for everyone. Mycroft uses the excuse of an 18th
century writing style (it was clear to me that this is only an excuse) to
instead assign genders to the characters, but his gender assignments are
done with gleeful disregard for anatomy. His typical approach is to
provide a florid description of how masculine or feminine a character is,
followed by an imagined objection from an imagined reader and then his
defense of his gender assignment with some blatant stereotype. Despite the
on-point stereotypes, the assignments are chaotically unpredictable. I
frequently guessed Mycroft would choose one gender, only to have him
choose the opposite and then credibly defend it via some entirely
different stereotype that hadn&#39;t occurred to me.
&lt;/p&gt;

&lt;p&gt;
I thought this was a highly entertaining and pointed commentary on how
absurd and contradictory our gender conventions and constructions are, but
the digressions and obviously fake and faux-archaic reader objections can
also get annoying. The objection I wanted to make, as an actual reader,
was more often something along the lines of &quot;oh my god, Mycroft, just pick
a pronoun and get on with the story, no one cares.&quot; Which is, itself,
biting meta-commentary on our obsession with gender that I had to admire
even when I was exasperated by it.
&lt;/p&gt;

&lt;p&gt;
So much of the book is like this: extremely clever, but also kind of
irritating. &lt;cite&gt;Too Like the Lightning&lt;/cite&gt; is one of the best examples of
cognitive estrangement in science fiction that I&#39;ve read, in part because
it&#39;s more social than technological. The technology here is standard
science fiction fare, but society has changed far more than technology has
in Palmer&#39;s future world. All (I think?) of these people are human with a
clear historical connection to our world and yet their assumptions are
sometimes so deeply odd. Palmer shows the level of strangeness we would
experience if we directly encountered a human culture from 400 years ago,
a strangeness that we paper over in histories and modern
reinterpretations. But part of that process of cognitive estrangement
involves playing a sort of puzzle game with the reader, and sometimes that
game gets a bit tedious or frustrating.
&lt;/p&gt;

&lt;p&gt;
The one place where the world-building fell flat for me, and kept knocking
me out of the story, is the politics. Not the Hives and the system of
ideology-based affiliation and geographic mixing; that&#39;s strange but
interesting, and I could buy it as a side effect of both catastrophe and
ubiquitous cheap transportation. Not the complicated system of legal codes
and exceptions and competing jurisdictions; that felt believably baroque
in the way that complexity emerges in the friction in long-lived human
systems. My problem was with the scale, or rather the lack of scale.
&lt;/p&gt;

&lt;p&gt;
This world has ten billion people; there is no way that the relationships
between literally every politically important person in the world could be
this incestuous. There are nowhere near enough factions, disagreements,
alternative power bases, petty personal grudges provoking serious schisms,
or enough &lt;em&gt;bureaucrats&lt;/em&gt;. I know there are myriad science fiction
novels with even more trivial and unbelievable world governments, but
usually they&#39;re not central to a highly political plot. &lt;cite&gt;Too Like the
Lightning&lt;/cite&gt; wants you to care deeply about the politics of this world and
then gives you a system in which all major decisions roll up to a handful
of people with apparently next to no intervening civil service.
&lt;/p&gt;

&lt;p&gt;
Also, why is there so little redundancy? How can the most vital service of
this civilization be run directly and almost exclusively by the
inhabitants of &lt;em&gt;one house?&lt;/em&gt; There is a technical explanation, but the
social explanation is barely handwaving. This is not how institutional
trust generally works; even with vast multinational high-capital
near-monopolies such as cloud computing, there are three major players and
innumerable smaller ones.
&lt;/p&gt;

&lt;p&gt;
Maybe Palmer was extrapolating from the global oligarch class and meetings
such as the &lt;a href=&quot;https://en.wikipedia.org/wiki/World_Economic_Forum&quot;&gt;World Economic Forum&lt;/a&gt;, which do indeed attract a startling percentage of
all world political figures. The problem, though, is not the surface of
occasional gatherings or staged events seen early in this story. It goes
much deeper, far into confidences and explicit coordination, to the extent
that at several points I said some variation of &quot;oh come on, there&#39;s no
way Mycroft personally knows them &lt;em&gt;too&lt;/em&gt;.&quot; The only people who believe
in controlling cabals this small are conspiracy theorists. This is simply
not how humans work when this much power is at stake.
&lt;/p&gt;

&lt;p&gt;
Now, I have to say that I&#39;m going out on a limb making this critique after
only reading the first book of a four-book series. This is absolutely the
type of work for which my reaction and objections could be an intentional
effect created by Palmer in order to spring some unexpected justification
on the reader in book two or three. It&#39;s clear that there is some massive
social upheaval on the horizon in this series, and something very strange
is going on with one of the characters and their hold over other people.
Perhaps the reader disbelief is setting up that upheaval. If so, hats off
to her, and that&#39;s one of the perils of reviewing books as I read them.
&lt;/p&gt;

&lt;p&gt;
But it still hurt my enjoyment of this book when the political drama kept
shrinking and tightening and focusing on fewer and fewer people. It felt
frankly unbelievable for the political universe of this highly political
book to be this claustrophobic. I wanted it to expand into the space that
should be available to an entire world teeming with fractious and complex
humanity.
&lt;/p&gt;

&lt;p&gt;
The other major complaint I have about this book is that the first-person
narrator is odious. This is something I knew going in — &lt;cite&gt;Too Like the
Lightning&lt;/cite&gt; famously has an unreliable and unlikable narrator — and he is
relatively passive for much of the book, so it is often possible to ignore
him and focus on more likable characters. I don&#39;t necessarily mind an
unlikable or unreliable narrator in this type of story.
&lt;/p&gt;

&lt;p&gt;
But, unfortunately, Mycroft cringes, and I hate reading about cringing for
this many pages. His primary mode of interaction with people is
obsequious, performative fear with a weird, distasteful edge of
manipulation. Again, I think this is entirely intentional on Palmer&#39;s
part; we learn some of the reasons behind it by the end of this book, and
I&#39;m sure we&#39;ll learn more in future books. But, nonetheless, the overall
effect is a bit like reading a book narrated by
&lt;a href=&quot;https://en.wikipedia.org/wiki/Gr%C3%ADma_Wormtongue&quot;&gt;Gríma
Wormtongue&lt;/a&gt;. I can appreciate the narrative role of that character without
wanting to spend this much time in his head.
&lt;/p&gt;

&lt;p&gt;
I have very mixed feelings about this book. The overall construction is
brilliant; it&#39;s a beautiful puzzle of oddity and alienation that provides
great fun for the type of science fiction reader who wants to work out the
rules of a strange society without a lot of infodumping. There are a few
characters I adored: Eureka, for example, a set-set (a sort of human
computer in a way that reminded me of mentats in &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-441-17271-7.html&quot;&gt;&lt;cite&gt;Dune&lt;/cite&gt;&lt;/a&gt; but with better world-building) who steals every scene that
she&#39;s in. I was very invested in the world-building, fascinated by the
Utopians, and want to learn more about what&#39;s going on.
&lt;/p&gt;

&lt;p&gt;
On the other hand, the combination of Mycroft as a narrator and the weird
one-room play logic of global politics kept throwing me out of my reading
flow. It took me about a month to finish this book. The science fiction
and political fiction aspects of the story interested me more than Bridger
and whatever is going on with J.E.D.D. Mason, and I&#39;m worried that my
least-favorite aspects will be central to the rest of the story. I was
enjoying a smaller percentage of the scenes by the end of the book than I
was at the start, which is not a great sign.
&lt;/p&gt;

&lt;p&gt;
And yet, the ending absolutely worked on me. I don&#39;t want to stop here! I
will probably pick up the sequel, but I think it&#39;s going to take me a
while to brace myself for it.
&lt;/p&gt;

&lt;p&gt;
I have no idea whether to recommend this or not, since I think your
enjoyment will depend so much on the balance between the parts of the book
you find irritating and the parts of the book you find engrossing. I&#39;m
fairly sure most readers will find a little of both, but I have no idea
how to predict their relative weight. If you like cognitive estrangement,
this is great; I understand why so many science fiction reviewers rave
about this book. If you need to like the first-person protagonist, uh,
good luck. Maybe you&#39;ll have more tolerance for cringing than I do.
&lt;/p&gt;

&lt;p&gt;
The one thing I can say firmly about &lt;cite&gt;Too Like the Lightning&lt;/cite&gt; is that
it&#39;s &lt;em&gt;interesting&lt;/em&gt;. It may be worth reading just to see how people
are stretching the genre, even if you end up not liking the effect. But be
warned that this book does not so much end on a cliffhanger as suddenly
stop at some random, nondescript point on the road leading to the cliff.
The ending is deeply unsatisfying; you will need to read more if you want
to understand what&#39;s going on.
&lt;/p&gt;

&lt;p&gt;
Followed by &lt;cite&gt;Seven Surrenders&lt;/cite&gt;.
&lt;/p&gt;

&lt;p&gt;Rating: 7 out of 10&lt;/p&gt; </description> 
	<pubDate>Wed, 02 Sep 2026 02:44:00 +0000</pubDate>

</item> 
<item>
	<title>Russ Allbery: Review: Last Chance to Save the World</title>
	<guid>https://www.eyrie.org/~eagle/reviews/books/0-7564-1971-9.html</guid>
	<link>https://www.eyrie.org/~eagle/reviews/books/0-7564-1971-9.html</link>
     <description>  &lt;p&gt;Review: &lt;cite&gt;Last Chance to Save the World&lt;/cite&gt;, by Beth Revis&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;&lt;tr&gt;
    &lt;td&gt;Series:&lt;/td&gt;
    &lt;td&gt;Chaotic Orbits #3&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Publisher:&lt;/td&gt;
    &lt;td&gt;DAW Books&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Copyright:&lt;/td&gt;
    &lt;td&gt;April 2025&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;ISBN:&lt;/td&gt;
    &lt;td&gt;0-7564-1971-9&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Format:&lt;/td&gt;
    &lt;td&gt;Kindle&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Pages:&lt;/td&gt;
    &lt;td&gt;133&lt;/td&gt;
  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;
&lt;cite&gt;Last Chance to Save the World&lt;/cite&gt; is a far-future science fiction caper
novella and the conclusion of the trilogy that began with
&lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-7564-1947-6.html&quot;&gt;&lt;cite&gt;Full Speed to a Crash Landing&lt;/cite&gt;&lt;/a&gt;. This is a
direct sequel to &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-7564-1949-2.html&quot;&gt;&lt;cite&gt;How to Steal a Galaxy&lt;/cite&gt;&lt;/a&gt;,
picking up right after that story leaves off, but you don&#39;t have to
remember the details to enjoy this installment.
&lt;/p&gt;

&lt;p&gt;
Ada has finally achieved a (temporary, contingent) alliance with
government agent Rian White by convincing Rian that some things are more
important than Ada&#39;s disregard for the law. She&#39;s going to need his help.
They have once chance to save Earth from a new and even more malicious
round of capitalist environmental blackmail, and it&#39;s going to require
Rian&#39;s security access as well as all of Ada&#39;s heist skills.
&lt;/p&gt;

&lt;p&gt;
But first, a visit with Ada&#39;s mother, who lives in an old watchtower on
Malta and keeps pigeons.
&lt;/p&gt;

&lt;p&gt;
Each entry in this series has been a little shorter than the last, and
&lt;cite&gt;Last Chance to Save the World&lt;/cite&gt; is definitely a novella. This is a
great length for a heist story: enough room for some setup and a couple of
major plot twists, but short enough that the story can maintain a headlong
pace. Even in the third novella of a series and a novel&#39;s worth of time in
Ada&#39;s head, Revis has one major surprise for the reader left. And, as
usual, there&#39;s a lot of misdirection, sarcastic commentary, and the
delightful competence of a protagonist who puts considerable professional
effort into being underestimated.
&lt;/p&gt;

&lt;p&gt;
The bits with Ada&#39;s mother were great. This is the first time we&#39;ve seen
Ada have significant interactions other than her flirting and teasing of
Rian, and I loved seeing a different side of her. The heist itself was
satisfying, although not quite as good as &lt;cite&gt;How to Steal a Galaxy&lt;/cite&gt;.
Ada gets to throw a few more verbal daggers, but there are more events in
this installment and therefore more action and less dialogue. Ada&#39;s
commentary and dialogue is still my favorite part, though.
&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;
    For all that Rian says I like to break the law, it should be illegal
    for any one man to be both this dumb and this rich. It&#39;s astounding,
    really. Any of his employees could run circles around him, but it
    doesn&#39;t take brains to buy stuff. Strom Fetor sees nothing clearly
    except profit margins.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;
There is, of course, even more flirting and semi-fake romance. Those were
not my favorite part, mostly because while it&#39;s obvious what Rian sees in
Ada, it baffles me what Ada sees in Rian. I know the star-crossed romance
between the law man and the charismatic thief is an old fictional trope,
but I found it very hard to justify Rian&#39;s continuing commitment to his
law and government given the clear facts of this setting.
&lt;/p&gt;

&lt;p&gt;
Up until this novella, one could excuse Rian as the sort of person whose
belief in order, stability, and rules combines with possibly excessive
optimism to create a belief in an imperfect system. But here, Ada has
finally convinced Rian that some great evils truly will not be fixed by
following the rules. He&#39;s onboard, but somehow in a way that leads to
precisely no reconsideration, soul-searching, or breach in his commitment
to defending a clearly corrupt and failing political system.
&lt;/p&gt;

&lt;p&gt;
My objection is not that this is unrealistic; sadly, it&#39;s very realistic.
My objection is that Rian is dumber than a bag of hammers, I don&#39;t like
reading about his blind allegiance to a bad system, and I do not
understand how that goes with the sexy feelings. I&#39;m sure this is my lack
of understanding of physical affection overriding common sense, and Ada is
at least not a complete idiot about her attraction. But I felt like this
novella expected me to like Rian as more than a foil for Ada, and I very
much did not.
&lt;/p&gt;

&lt;p&gt;
That knocked a point off my enjoyment of this entry, but the heist is
great, the politics are interesting, and the climax was very satisfying.
This is not quite as good as the middle book of the trilogy, but it&#39;s a
satisfying conclusion. If you liked the previous entries, you&#39;ll want to
read this one for the conclusion.
&lt;/p&gt;

&lt;p&gt;
&lt;cite&gt;Last Chance to Save the World&lt;/cite&gt; resolves the main plot driver of the
trilogy, but there&#39;s a lot of space for more sequels. If they materialize,
I will probably keep reading, although I hope someone knocks some sense
into Rian.
&lt;/p&gt;

&lt;p&gt;Rating: 8 out of 10&lt;/p&gt; </description> 
	<pubDate>Tue, 01 Sep 2026 03:18:00 +0000</pubDate>

</item> 
<item>
	<title>Jonathan McDowell: What do I want in a Linux distribution?</title>
	<guid>https://www.earth.li/~noodles/blog/2026/08/what-do-i-want-distro.html</guid>
	<link>https://www.earth.li/~noodles/blog/2026/08/what-do-i-want-distro.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/noodles.png&quot; width=&quot;100&quot; height=&quot;108&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;I’ve been a &lt;a href=&quot;https://www.debian.org/&quot;&gt;Debian&lt;/a&gt; user since 1999, and a Debian developer &lt;a href=&quot;https://nm.debian.org/legacy/process/13424/&quot;&gt;since 2000&lt;/a&gt;. Given &lt;a href=&quot;https://www.debian.org/vote/2026/vote_002&quot;&gt;recent events&lt;/a&gt; it’s worth thinking about why that that is, and why I haven’t switched to something else in the past quarter century.&lt;/p&gt;

&lt;p&gt;My first Linux distro was &lt;a href=&quot;http://www.slackware.com/&quot;&gt;Slackware&lt;/a&gt;, off a CD in a book, some time in the mid 90s. After starting university I ran &lt;a href=&quot;https://www.suse.com/&quot;&gt;SUSE&lt;/a&gt; for a while, then moved to &lt;a href=&quot;https://www.redhat.com/&quot;&gt;RedHat&lt;/a&gt; (both back before they had commercial variants significantly different to what was available freely). The main motivation for switching was package management; I was running a machine at home, and a machine at university. Keeping track of what was installed on each, and what versions, was getting annoying with Slackware. Most of the folk I knew were running RedHat, and I mostly played with SUSE because I’m contrary before realising it was different enough that I couldn’t easily make use of 3rd party RPMs.&lt;/p&gt;

&lt;p&gt;I came to Debian via friends in Cambridge, who spoke highly of it. The first Debian machine I installed was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fourier&lt;/code&gt;, the initial host for Black Cat Networks, and I never looked back.&lt;/p&gt;

&lt;p&gt;(For additional context I should also point out I have contributed, in the distant past, to, and run, &lt;a href=&quot;https://openwrt.org/&quot;&gt;OpenWRT&lt;/a&gt;, &lt;a href=&quot;https://www.openembedded.org/&quot;&gt;OpenEmbedded&lt;/a&gt;, and &lt;a href=&quot;https://www.freebsd.org/&quot;&gt;FreeBSD&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;I’d like to try and work out what is it I get from Debian that I’d need in anything else. Originally I tried to order the requirements in some sort of priority, but it’s sometimes hard to work out what I’d drop if I had to compromise somewhere, so it’s a somewhat loose ordering.&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;Stable releases, with security support&lt;/dt&gt;
  &lt;dd&gt;I run Linux in lots of places, from remote servers/VMs, to my house router, to my desktop/laptop. Some of those I don’t want to be updating regularly with new software releases, I need something I can be sure is going to keep working, but will get necessary security + critical updates. A rolling distro that provides security via the latest upstream release doesn’t provide that guarantee. Equally there need to be regular stable releases, or things become too stale. (The one time I considered moving away from Debian was during the 3 year &lt;a href=&quot;https://www.debian.org/releases/sarge/&quot;&gt;Sarge / 3.1&lt;/a&gt; release cycle. I think if things hadn’t improved I’d have jumped ship to &lt;a href=&quot;https://ubuntu.com/&quot;&gt;Ubuntu&lt;/a&gt; at the time.)&lt;/dd&gt;
  &lt;dt&gt;A good selection of packages&lt;/dt&gt;
  &lt;dd&gt;One of the reasons I moved from RedHat to Debian was the wide range of packages available as part of the standard OS. Pulling it all into the distro helps with quality control, compared to random 3rd party packages. A centralised bug system and repository is a win too. Perhaps packages at all is something I should list, but I take it as a given if you’re running a distro. I need to know what I have installed on my machine, what version that software is, what files it owns, and what it depends on.&lt;/dd&gt;
  &lt;dt&gt;Free Software&lt;/dt&gt;
  &lt;dd&gt;This is important to me. I’ll make pragmatic compromises about software I run on my systems if it makes sense, but I want to start from a place that does not require anything non-free. I’ve run a company on Debian, and I’ve worked on numerous products that ran it under the hood. The &lt;a href=&quot;https://www.debian.org/social_contract#guidelines&quot;&gt;DFSG&lt;/a&gt; give me confidence I can do that.&lt;/dd&gt;
  &lt;dt&gt;Smooth upgrades&lt;/dt&gt;
  &lt;dd&gt;Debian’s ability to upgrade a system smoothly is one of the reasons I first moved to it. The first upgrade I did was remotely on a machine sitting on a 2Mb/s leased line. I was nervous doing the reboot at the end, but it came back fine. At the time the equivalent procedure with RedHat involved rebooting into the OS installer to do the upgrade.&lt;/dd&gt;
  &lt;dd&gt;I know things have moved on since then, and really it should all be scripted, and machines should be cattle not pets, but for personal use I run a small enough number of machines that having the upgrade path between releases is a must have.&lt;/dd&gt;
  &lt;dt&gt;Community&lt;/dt&gt;
  &lt;dd&gt;The original pull of the Debian community was the knowledge I could get involved, and upload packages that were missing that I was using. That’s how I first got involved, uploading things Black Cat used, which made life easier for us in the long run. I don’t have time to maintain all the software I use myself, and I don’t want to be beholden to a commercial entity to do so for me, so a distribution that allows me to help out where I can as part of the community seems to me to be the right way to do things.&lt;/dd&gt;
  &lt;dt&gt;Architecture support&lt;/dt&gt;
  &lt;dd&gt;Perhaps less important, especially when I started using Debian, but these days I have amd64, arm64, armhf, and riscv machines. Everything except for the risvc box is doing something useful, and would need replaced if I couldn’t keep running it, and I expect RISC-V to transition into that state in the next few years as the hardware improves.&lt;/dd&gt;
  &lt;dt&gt;Binary packages&lt;/dt&gt;
  &lt;dd&gt;I ran a FreeBSD desktop for some time. It might have been the way I was holding it, but binary package installs were generally not something reliable, especially after the initial install, and I ended up building things from ports from source quite often. That worked incredibly well (I used to think people who raved about &lt;a href=&quot;https://www.gentoo.org/&quot;&gt;Gentoo&lt;/a&gt; really should just go do it properly and use FreeBSD), but I don’t want to spend time compiling things, especially on some of my machines (my router should not need a compiler, for example).&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;Ultimately I don’t want to have to actively think about the Linux distribution I use. Debian has mostly given me that; I know it will generally be suitable for most environments I want to use it in (embedded situations where OpenWRT or OpenEmbedded are better choices being the exception, but that’s less frequent these days), and I can rely on getting timely security updates (thanks to all those who work on that within Debian!). I’m not sure there’s currently an alternative that would suit my needs? I’d love to hear if there’s something I should look at, even if I’m not necessary making a move just yet!&lt;/p&gt; </description> 
	<pubDate>Mon, 31 Aug 2026 17:20:15 +0000</pubDate>

</item> 
<item>
	<title>Russ Allbery: Review: The Hands of the Emperor</title>
	<guid>https://www.eyrie.org/~eagle/reviews/books/1-988908-15-9.html</guid>
	<link>https://www.eyrie.org/~eagle/reviews/books/1-988908-15-9.html</link>
     <description>  &lt;p&gt;Review: &lt;cite&gt;The Hands of the Emperor&lt;/cite&gt;, by Victoria Goddard&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;&lt;tr&gt;
    &lt;td&gt;Series:&lt;/td&gt;
    &lt;td&gt;Lays of the Hearth-Fire #1&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Publisher:&lt;/td&gt;
    &lt;td&gt;Underhill Books&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Copyright:&lt;/td&gt;
    &lt;td&gt;January 2019&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;ISBN:&lt;/td&gt;
    &lt;td&gt;1-988908-15-9&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Format:&lt;/td&gt;
    &lt;td&gt;Kindle&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Pages:&lt;/td&gt;
    &lt;td&gt;739&lt;/td&gt;
  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;
&lt;cite&gt;The Hands of the Emperor&lt;/cite&gt; is a self-published political fantasy
novel. It&#39;s the recommended first book (although not the first published
book) in a
&lt;a href=&quot;https://nineworlds.miraheze.org/wiki/Reading_Order&quot;&gt;complicated set
of interrelated series&lt;/a&gt;. I was not able to definitively confirm that
Underhill Books is Goddard&#39;s self-publishing press name, but the press
does not appear to have an Internet presence apart from Goddard&#39;s books
and her books appear to be using the standard self-publishing channels.
&lt;/p&gt;

&lt;p&gt;
Cliopher Mdang is the personal secretary of the last emperor of
Astandalas, the magical heart of Zunidh, a man worshiped as a god. The
emperor&#39;s word is absolute, his magic supports the health of the entire
world, and he cannot be physically touched without risking physical damage
and severe political and religious punishment. Cliopher is one of the
emperor&#39;s closest associates, but the distance between them is still vast.
It therefore represents a terrifying and dangerous breach of etiquette for
him to suggest the emperor may enjoy a vacation on a tropical island near
Cliopher&#39;s remote home. The emperor&#39;s acceptance of the invitation is even
more startling.
&lt;/p&gt;

&lt;p&gt;
The emperor has opinions about his life as the emperor that no one had
guessed. Cliopher has not assimilated as completely into the bureaucratic
machinery of the empire as it first may appear. And Cliopher&#39;s family have
vastly misunderstood the nature of his role in the emperor&#39;s government.
&lt;/p&gt;

&lt;p&gt;
I find the marketing blurb for this book unfortunate since, at least to
me, the emphasis on physical touch and intimacy implies that &lt;cite&gt;The
Hands of the Emperor&lt;/cite&gt; is a romance novel or at least has significant
romantic elements. I&#39;ve been aware of this book for years but put off
reading it because I wasn&#39;t quite in the mood for that story. This is not
a romance novel; there is no romance in this book whatsoever. It is a
political fantasy, both in the sense that it is set in a secondary fantasy
world with magic and (apparently) some form of interplanetary travel, and
in the sense that it is a fantasy of governance.
&lt;/p&gt;

&lt;p&gt;
When I say that this book blew up in certain corners of the Internet
during the pandemic, I think you will still underestimate the passion of
its advocates. I heard about this book &lt;em&gt;constantly&lt;/em&gt;, in a way that
reminded me of &lt;a href=&quot;https://www.eyrie.org/~eagle/reviews/books/0-765-34298-7.html&quot;&gt;&lt;cite&gt;Kushiel&#39;s Dart&lt;/cite&gt;&lt;/a&gt; and the
time when fans of Jacqueline Carey would bring her up in every fantasy
conversation, or when we created a Usenet newsgroup for &lt;cite&gt;The Wheel of
Time&lt;/cite&gt; mostly to get the voluminous conversations off of the regular SFF
newsgroup. I&#39;m one of those mildly contrarian people for whom that degree
of enthusiasm is a little off-putting, which is another reason why I
resisted buying a copy for years and only read it in 2026.
&lt;/p&gt;

&lt;p&gt;
It&#39;s delightful, although also a bit embarrassing, when the book everyone
was in love with turns out to be just as good as everyone said it was.
&lt;/p&gt;

&lt;p&gt;
I adore stories about friendship, and this is one of the best stories
about friendship that I&#39;ve ever read. It is a very, very slow burn, but I
also thought the first three quarters of the book was exquisitely paced.
There were long sections where not very much was happening, and yet I
couldn&#39;t put the book down because there was so much subtle character work
just beneath the surface.
&lt;/p&gt;

&lt;p&gt;
Almost all of the novel is told in tight third person from Cliopher&#39;s
perspective, and I thought that was an excellent choice. Neither Cliopher
nor the narrator comment on things that Cliopher finds obvious, which is
both immersive and critical to the pacing. There are discoveries for the
reader throughout the book, the sort of discoveries that make pieces fit
together satisfyingly in retrospect, and the reader stays sufficiently
ahead of the misunderstandings of Cliopher&#39;s friends and family that one
also gets the joy of watching other people discover things that one
figured out a hundred pages earlier.
&lt;/p&gt;

&lt;p&gt;
It helps that I truly liked nearly everyone in this book. There are no
real villains, only a few supporting characters whose role is to be
irritating or corrupt. If you&#39;re looking for a lot of conflict and drama,
you may want to save this book for a different mood, but if you&#39;re in the
mood for a varied collection of fundamentally good characters working
methodically through the complexities and obstacles of politics and social
systems to improve the world, there are few books I would recommend more.
Goddard achieves one of the hardest tricks of slow burns: steady forward
progress that does not rely on reversals, misunderstandings, or the
friendship equivalent of the third-act breakup. This book spends 700 pages
building towards a climax that managed to be worthy of all 700 pages
without ever annoying me with artificial obstacles, and that&#39;s quite a
feat.
&lt;/p&gt;

&lt;p&gt;
I&#39;ve not said much about the details of the plot. There is one — it&#39;s not
just character work — but I think this book benefits immensely from going
in as blind as possible. I found the twists and turns and growing
revelations so deeply satisfying that I don&#39;t want to rob any other reader
of the experience.
&lt;/p&gt;

&lt;p&gt;
The fantasy world-building is intriguing but a bit unsatisfying because it
is so unexplained. We get a few details of the magic system, but since
Cliopher has no magic, he isn&#39;t that interested in the details. There is a
catastrophic magical event in the world background, and we learn some of
the details of its practical effects, but the nature of the world before
the cataclysm is so obvious to the characters that it&#39;s never explained.
I&#39;m not even certain that this civilization is interplanetary; that feels
like the implication of how characters talk about multiple worlds, but the
method of travel is left entirely undefined. This might be frustrating to
some genre readers, but I personally enjoy books where the world-building
is a bit mysterious. It&#39;s a good reason to read more of Goddard&#39;s books
set in the same universe.
&lt;/p&gt;

&lt;p&gt;
This was my favorite of the books I&#39;ve read so far this year, but I do
have one caution and a couple of caveats.
&lt;/p&gt;

&lt;p&gt;
The caution is that Cliopher comes from an island culture based heavily on
(I think) Polynesian cultures. That culture is very central to the story
and is treated with considerable respect, but I still get a bit nervous
when a Canadian author from Nova Scotia with an academic background in
European medieval studies writes a story focused this deeply on a
non-European culture. Nothing about her portrayal seemed off to me
(although there is a very clunky and ham-handed scene about a different
native culture that worries me), and for all I know she has family
background or other connections to the culture she is borrowing from, but
it&#39;s possible I missed serious problems.
&lt;/p&gt;

&lt;p&gt;
The flip side of that caution is that I&#39;m delighted to see a fantasy
author drawing on a non-European culture, and I thought the clash of
cultures was very well-handled.
&lt;/p&gt;

&lt;p&gt;
The first caveat is that the story is very focused on good governance, but
both the process and the details of that governance are not going to
satisfy someone reading primarily for the politics. The policies and
reforms are very standard 21st century progressive material that felt a
bit out of place in a quasi-medieval world with magic and airships. Their
implementation is not the point of the story, and is therefore heavily
backgrounded, but that means Goddard barely mentions the inevitable
practical implementation difficulties and does not discuss how they&#39;re
overcome.
&lt;/p&gt;

&lt;p&gt;
The world structure also means that Goddard can make use of the favorite
cheat of political reformers in fiction: Absolute monarchy lets you enact
a political agenda without having to do the hard and frustrating work of
persuasion or political (or actual) warfare. This objection is not
entirely fair because we do get some memorable scenes of persuasion, but
the political portion of the plot is unrealistically devoid of setbacks or
resistance that goes beyond token arguments.
&lt;/p&gt;

&lt;p&gt;
Whether this will bother you will depend heavily on what parts of the book
you&#39;d rather focus on. I can see why this was such a popular pandemic
read: &lt;cite&gt;The Hands of the Emperor&lt;/cite&gt; is focused tightly on the joy of
competent people fixing things and does not focus on the arguments,
division, or polarization. The heart of the book is the friendship and
characterization of some deeply admirable people, and the political reform
is incidental background material. I suspect this is the right choice for
readers who aren&#39;t political junkies, but I kept having the niggling
objection that the politics felt a bit too pat and simplistic. Goddard
stressed that the characters were investing considerable effort, but even
still, it is not this easy to change the direction of a political system
and idealistic plans usually do not work out this neatly.
&lt;/p&gt;

&lt;p&gt;
The second caveat is that, as previously mentioned, I thought the pacing
was excellent for about three quarters of the book. Goddard is building
towards a grand climax, and I think she built a little too much and tried
to make the climax a bit too grand and risked over-egging the pudding.
That made the payoff feel a bit belabored to me. I still enjoyed it, and
parts of it are wonderfully emotional, but I think the ending might have
been stronger if Goddard had dialed Cliopher back just a little and
tightened up the climax a touch. That said, this book fully commits to
being a sprawling slow burn and that&#39;s part of its appeal, so it&#39;s
probably better for Goddard to err in that direction than it would have
been to cut short the denouement.
&lt;/p&gt;

&lt;p&gt;
This is one of those books that I&#39;m not sure would exist without
self-publishing. It&#39;s a little too long, a little too political in the
wrong ways, a little too devoid of the typical sorts of conflicts expected
in a fantasy book, and too determined to be its own peculiar thing. I
think it would scare off publishers. Unlike some self-published books,
though, I didn&#39;t notice any obvious editing flaws or lack of polish. It&#39;s
one of those glorious novels that is so very much its own type of story
that it provides an experience that would be hard to replicate with
another book.
&lt;/p&gt;

&lt;p&gt;
I was so deeply satisfied by this book. It&#39;s a wish-fulfillment political
fantasy full of diligent restraint and competence porn, so you have to be
in the mood for that. This is not the book to read when you&#39;re feeling
cynical, or are in the mood for action and high drama. But if you&#39;re in
the mood for a long, slow, open-hearted story of friendship that offers
the fantasy of giving truly good people enough power to be effective, I
highly recommend this one.
&lt;/p&gt;

&lt;p&gt;
Followed in the direct sequel sense by &lt;cite&gt;At the Feet of the Sun&lt;/cite&gt;, but
there is a very complex story progression in this world that I think I&#39;d
have to read all the other books to understand. This was such a satisfying
and complete experience that I&#39;m not in a hurry to figure out which
Goddard book to read next, but I&#39;m sure I&#39;ll be returning to this world at
some point.
&lt;/p&gt;

&lt;p&gt;Rating: 9 out of 10&lt;/p&gt; </description> 
	<pubDate>Mon, 31 Aug 2026 03:11:00 +0000</pubDate>

</item> 
<item>
	<title>Ingo Juergensmann: Debian GR on Responsible Use of Generative AI</title>
	<guid>https://blog.windfluechter.net/?p=97337</guid>
	<link>https://blog.windfluechter.net/2026/08/29/debian-gr-on-responsible-use-of-generative-ai/</link>
     <description>  &lt;p class=&quot;wp-block-paragraph&quot;&gt;So, the members of Debian (developers and such) have voted in a &lt;a href=&quot;https://www.debian.org/vote/2026/vote_002&quot;&gt;GR about “LLM usage in Debian&lt;/a&gt;” for Option 5)/Proposal E) “Responsible Use of Generative AI”. &lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;And in the &lt;a class=&quot;hashtag u-tag u-category&quot; href=&quot;https://blog.windfluechter.net/tag/fediverse/&quot; rel=&quot;tag&quot;&gt;#Fediverse&lt;/a&gt; the hell breaks lose!&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Currently there is a huge vibe against (Generative) AI, i.e. generating code, images, etc. I can understand some furor about this and in general I dislike much of the AI as well. For example I dislike the energy and water consumption, what the hype did to memory &amp;amp; storage prices, the awful look of all these AI generated images, the ignorance of AI companies about copyrights and all this. &lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;But I also see the benefits of AI: people are entitled to do things they couldn’t do before. You can proceed faster with your pet project when AI assist you and all of the bells and whistles. &lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;Anyway, let’s face it: AI is a disruptive technolgy like the invention of electricity, the steam engine, combustion engine, the computer or the smartphone were. It will not go away anymore. Pandoras box is open. &lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;But what you can do is: &lt;/p&gt;



&lt;ul class=&quot;wp-block-list&quot;&gt;
&lt;li&gt;learn what AI is and what not&lt;/li&gt;



&lt;li&gt;use AI in a responsible way&lt;/li&gt;



&lt;li&gt;experience the Do’s &amp;amp; Don’ts of AI&lt;/li&gt;



&lt;li&gt;increase your knowledge about AI and its dangers and beneftis&lt;/li&gt;



&lt;li&gt;help others with getting used resonsibly to AI&lt;/li&gt;



&lt;li&gt;build a good sense that AI is telling you nonsense&lt;/li&gt;



&lt;li&gt;don’t blindly trust AI&lt;/li&gt;



&lt;li&gt;learn about new technology with and without the help of AI&lt;/li&gt;



&lt;li&gt;use it as a tool&lt;/li&gt;



&lt;li&gt;etc…&lt;/li&gt;
&lt;/ul&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;I don’t say you should embrace AI completely, but demonizing it won’t help you either. Be sceptic, be curious about it, act responsible. AI is not your saviour, but it’s also not armageddon. It is a discruptive technology. Deal with it. You’ll have no other option anyway. ðŸ¤·â€�â™‚ï¸�&lt;/p&gt;



&lt;p class=&quot;wp-block-paragraph&quot;&gt;&lt;/p&gt; </description> 
	<pubDate>Sat, 29 Aug 2026 07:40:00 +0000</pubDate>

</item> 
<item>
	<title>Joey Hess: Debian and the sirens</title>
	<guid>http://joeyh.name/blog/entry/Debian_and_the_sirens/</guid>
	<link>http://joeyh.name/blog/entry/Debian_and_the_sirens/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/joeyh2.png&quot; width=&quot;84&quot; height=&quot;75&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;Thirty years ago I became a Debian developer. Twelve years ago I left the
project. I left because it seemed that the Debian ship had become too slow
to turn, too barnacled with a series of individually OK decisions that each
added a little bit of friction and a little less flexability. That made
Debian strongly what it is, but prevented it from fruitfully exploring
the vast possibility space of what it could be.&lt;/p&gt;

&lt;p&gt;Debian will probably &lt;a href=&quot;https://www.debian.org/vote/2026/vote_002&quot;&gt;resolve&lt;/a&gt;
today to allow LLM use in Debian development. I&#39;m writing before the vote
results are in, but will only post this afterwards. (Update: as expected)
It&#39;s not my place any longer to try to steer the ship. But I&#39;m still a
passenger and I still have opinions, and I still pass by well-worn parts of
the rigging that I put up decades ago, and remember what I was trying to
accomplish back then.&lt;/p&gt;

&lt;p&gt;When I think about LLMs in Debian development, I mostly think about
&lt;a href=&quot;http://joeyh.name/code/debhelper/&quot;&gt;debhelper&lt;/a&gt; and what it accomplished. The &lt;code&gt;debian/rules&lt;/code&gt; files back
when I joined the project were long and complex, full of weird boilerplate,
and often you&#39;d copy one and modify it to try to get something that could
build a package without too much work. Debhelper first regularized the
boilerplate, so packages had rules files that were a succession of &lt;code&gt;dh_&lt;/code&gt;
commands, and then it scapped almost all of the boilerplate, reducing the
files to the minimum possible. What was left was 3 lines of unncessary
boilerplate, there only to satisfy a legalistic reading of a policy
document. Changing that to eliminate the boilerplate was already
impossible, even though the actual benefit would have been large over the
many thousands of packages in the distribution.&lt;/p&gt;

&lt;p&gt;What LLMs in Debian development will do, I fear, is eliminate any incentive
to scrap boilerplate or reform policies that require a lot of other
senseless human effort. If I had had access to LLMs 30 years ago, I
might have just had them generate the rules files, replate with
complexity. So they will make Debian even more firmly what it is, and
ever less likely to explore what it could become.&lt;/p&gt;

&lt;p&gt;Unfortunately, one of the things that Debian is, is almost unable to manage
packaging modern dependency trees. While more recent distributions like
Guix can &lt;a href=&quot;https://guix.gnu.org/manual/1.5.0/en/html_node/Invoking-guix-import.html&quot;&gt;recursively import dependencies&lt;/a&gt;
from a dozen programming languages&#39; package repositories, with a result
that is generally acceptable to add to the distribution, Debian&#39;s policies
don&#39;t make that very possible for a progam to accomplish. Perhaps some will
use LLMs to do that. If they succeeed, Debian will become dependent on
proprietary software for development, while still needing people in the
loop, doing even less appealing scut-work.&lt;/p&gt;

&lt;p&gt;I could speak of other harms, but that alone is enough that I&#39;m sure that,
if I had not left the project twelve years ago, I would be leaving it soon.
As a passenger, I imagine I&#39;ll spend time aboard still from time to time,
but it&#39;s certainly time to hop off in different places and look around and
relish the different ways.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://kitenet.net/~errol/&quot;&gt;I lost a parent yesterday&lt;/a&gt;, and I&#39;m trying
hard not to think of the results today as having lost a child, though I
spent 18 years helping Debian grow up. That would be too unbearably
painful. I respect that Debian is navigating a choice that may have no
right answer. Whichever particular compromise is arrived at today, it will
still be up to individuals to make choices about what they do and accept.
Debian has always been more than the sum of its policies, not just a ship,
but a crew. I will always love you.&lt;/p&gt; </description> 
	<pubDate>Sat, 29 Aug 2026 00:27:55 +0000</pubDate>

</item> 
<item>
	<title>Antoine Beaupré: A more nuanced view of LLMs</title>
	<guid>https://anarc.at/blog/2026-08-25-llm-nuance/</guid>
	<link>https://anarc.at/blog/2026-08-25-llm-nuance/</link>
     <description>  &lt;blockquote&gt;&lt;p&gt;Also in this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://anarc.at/blog/2026-05-16-four-horsemen/&quot;&gt;The Four Horsemen of the LLM Apocalypse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://anarc.at/blog/2026-08-18-people-vs-ai-overlords/&quot;&gt;The people vs the AI overlords&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;After ranting and railing about LLMs or &quot;AI&quot; as the optimists (or
&lt;a href=&quot;https://en.wikipedia.org/wiki/Accelerationism&quot;&gt;accelerationists&lt;/a&gt;?)  call it, I figured it might be important to
be a little more honest about my use of LLMs and how I think about it
more practically in the world.&lt;/p&gt;

&lt;h1 id=&quot;the-debian-vote-context&quot;&gt;The Debian vote context&lt;/h1&gt;

&lt;p&gt;This is not a coming out. I am not using LLMs on a daily basis, and
this blog is, again, written out of my cold dead hands in a dying
world, with over-engineered hardware and (to a certain extent, hi
Emacs!) software, powered by 100% green energy built on &lt;a href=&quot;https://en.wikipedia.org/wiki/James_Bay_Cree_hydroelectric_conflict&quot;&gt;stolen land&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is a &lt;a href=&quot;https://www.debian.org/vote/2026/vote_002&quot;&gt;vote going on in Debian&lt;/a&gt;. If you&#39;re unfamiliar with it,
you can &lt;a href=&quot;https://lwn.net/SubscriberLink/1087134/77bf350b3d40bc95/&quot;&gt;catch up at LWN&lt;/a&gt;. So far I&#39;ve essentially said &quot;LLM is
bad&quot; which is not a very balanced or useful opinion. Obviously, people
are using LLMs, sometimes unknowing or unwillingly, and we need to
take that into account. Furthermore, there has been many different
blog posts on Debian planet about this. Some that I found
&lt;a href=&quot;https://grep.be/blog//en/computer/debian/Programming_and_GR_2026_002/&quot;&gt;balanced&lt;/a&gt;, &lt;a href=&quot;https://diziet.dreamwidth.org/20998.html&quot;&gt;good summaries&lt;/a&gt;, even if I &lt;a href=&quot;https://changelog.complete.org/archives/44740-ai-in-debian-the-vote-proposals-and-nuance&quot;&gt;didn&#39;t fully agree&lt;/a&gt; &lt;a href=&quot;https://raphaelhertzog.com/2026/08/26/debians-general-resolution-on-ai-and-llm/&quot;&gt;with
them&lt;/a&gt;, at least some did the basic civil service of being
&lt;a href=&quot;http://blog.fai-project.org/posts/llm-usage-gr/&quot;&gt;short&lt;/a&gt;. But others were just not only &lt;a href=&quot;https://k1024.org/posts/2026/2026-08-23-another-optimistic-take-on-ai/&quot;&gt;Wrong&lt;/a&gt; but also &lt;a href=&quot;http://aigarius.com/blog/2026/08/22/optimistic-take-on-ai/&quot;&gt;so long
that I couldn&#39;t finish&lt;/a&gt; that I just &lt;em&gt;had&lt;/em&gt; to write &lt;em&gt;something&lt;/em&gt;.&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;https://anarc.at/tag/debian-planet/#fn:1&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;This is not an explanation of the ballots, nor how I will vote. This
vote is Debian&#39;s failure of framing that debate in a reasonable way:
we have 8 options on the ballot with many duplicates. We have failed
to do the hard work of summarizing and aggregating options into a
meaningful set. I doubt the final vote will represent a readable
position we can rally around.&lt;/p&gt;

&lt;p&gt;I have not read the &lt;a href=&quot;https://lists.debian.org/debian-vote/2026/07/threads.html&quot;&gt;two&lt;/a&gt; &lt;a href=&quot;https://lists.debian.org/debian-vote/2026/08/threads.html&quot;&gt;months&lt;/a&gt; of debates on the topic
either. Normally, before voting, I take a cursory look at the debate
to see points of view I might have missed. But in this case, it will
just make me sad, add noise, and I&#39;m already pretty sure on where I
stand on this.&lt;/p&gt;

&lt;p&gt;So let me describe how I use LLMs and how I think they fit in our
work, as computer engineers and hobbyists.&lt;/p&gt;

&lt;h1 id=&quot;my-llm-use&quot;&gt;My LLM use&lt;/h1&gt;

&lt;h2 id=&quot;debian-packaging&quot;&gt;Debian Packaging&lt;/h2&gt;

&lt;p&gt;An astute reader has &lt;a href=&quot;https://piaille.fr/@TurboTrain/117067460922413248&quot;&gt;pointed out&lt;/a&gt; that I maintain a package in
Debian made to use Anthropic. It&#39;s actually multiple packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/llm&quot;&gt;&lt;code&gt;llm&lt;/code&gt;&lt;/a&gt;: a &lt;a href=&quot;https://llm.datasette.io/en/stable/&quot;&gt;CLI utility and Python library for interacting with
Large Language Models&lt;/a&gt;, with OpenAI as its default API backend&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/llm-anthropic&quot;&gt;&lt;code&gt;llm-anthropic&lt;/code&gt;&lt;/a&gt;: a plugin for &lt;code&gt;llm&lt;/code&gt; which allows me to talk to
Anthropic&#39;s API instead of OpenAI&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tracker.debian.org/pkg/anthropic-sdk-python&quot;&gt;&lt;code&gt;anthropic-sdk-python&lt;/code&gt;&lt;/a&gt;: the SDK &lt;code&gt;llm-anthropic&lt;/code&gt; requires to do
its work&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;As I previously &lt;a href=&quot;https://kolektiva.social/@Anarcat/117071797145506717&quot;&gt;explained in response&lt;/a&gt;, I am not entirely
comfortable with this work: it&#39;s a compromise. In fact, I first
uploaded &lt;code&gt;llm&lt;/code&gt; to the &lt;code&gt;contrib&lt;/code&gt; section of Debian, where we keep
software that depends on other non-free software, but I was told that,
since &lt;a href=&quot;https://tracker.debian.org/pkg/yt-dlp&quot;&gt;&lt;code&gt;yt-dlp&lt;/code&gt;&lt;/a&gt; was in &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;llm&lt;/code&gt; belonged there as well.&lt;/p&gt;

&lt;p&gt;So I &lt;a href=&quot;https://tracker.debian.org/news/1718613/accepted-llm-028-2-source-all-into-unstable/&quot;&gt;moved it to main&lt;/a&gt;, alongside similarly controversial tools
like &lt;a href=&quot;https://tracker.debian.org/pkg/llama.cpp&quot;&gt;&lt;code&gt;llama.cpp&lt;/code&gt;&lt;/a&gt; or the &lt;a href=&quot;https://tracker.debian.org/pkg/python-openai&quot;&gt;&lt;code&gt;python-openai&lt;/code&gt;&lt;/a&gt; library.&lt;/p&gt;

&lt;h2 id=&quot;openai-and-anthropic-usage&quot;&gt;OpenAI and Anthropic usage&lt;/h2&gt;

&lt;p&gt;An important part of my work is technology watch. I keep tabs on
thousands of (new and old) software projects, follow news, and
generally try to keep my skills up to date. It&#39;s a &lt;a href=&quot;https://anarc.at/blog/2018-05-26-kubecon-rant/&quot;&gt;pretty impossible
race&lt;/a&gt;, especially as I grow older, but I still think I&#39;m doing the
right choices in my job.&lt;/p&gt;

&lt;p&gt;Testing large language models is part of that work. At first, I was
using ChatGPT&#39;s web interface, but it was annoying to copy-paste
things into a browser, so I looked for different interfaces.&lt;/p&gt;

&lt;p&gt;For a while I tried &lt;a href=&quot;https://github.com/karthink/gptel&quot;&gt;&lt;code&gt;gptel&lt;/code&gt;&lt;/a&gt;, a &quot;simple, extensible LLM client for
Emacs&quot; but I found it kind of terrifying. Giving a LLM control over an
Emacs buffer seems like a security nightmare, so I &lt;a href=&quot;https://gitlab.com/anarcat/emacs-d/-/commit/57fb1c13e63b58142ece426fc32f4ebdb325a6c3&quot;&gt;stopped doing
that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So I use the &lt;code&gt;llm&lt;/code&gt; command-line tool to talk to Anthropic&#39;s API. I
started that in the summer of 2025, when I bought 20$USD of API
credits. Before that, I paid for a ChatGPT subscription and then
OpenAI credits, which expired and sent me over to Anthropic, which
&lt;em&gt;seemed&lt;/em&gt; then to have better ethics.&lt;/p&gt;

&lt;p&gt;As it turns out, Anthropic is also happy to work for the US military
(which is a big red line for me). Anthropic also won&#39;t let you &lt;a href=&quot;https://evanp.me/2026/07/23/claude-wont-let-me-talk-about-the-gaza-genocide/&quot;&gt;talk
about the genocide in Gaza&lt;/a&gt;, it is &lt;a href=&quot;https://annas-archive.gl/blog/physical-destruction.html&quot;&gt;destroying physical books&lt;/a&gt;,
and is &lt;a href=&quot;https://www.flyingpenguin.com/mythos-grading-mythos-got-patches-yet/&quot;&gt;blackmailing us to use their product for security
coverage&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Needless to say, Anthropic and &quot;Claude&quot; are not my friends, but they
seem like the lesser evil in current &quot;frontier models&quot;. So I have
renewed, a couple of weeks ago, another 20$USD of API credits with
Anthropic.&lt;/p&gt;

&lt;h2 id=&quot;actual-prompts-and-responses&quot;&gt;Actual prompts and responses&lt;/h2&gt;

&lt;p&gt;So what does 20$ give you at Anthropic anyways? What &lt;em&gt;am&lt;/em&gt; I using LLMs
for and how?&lt;/p&gt;

&lt;p&gt;The neat thing with &lt;code&gt;llm&lt;/code&gt; is that everything is logged in a &lt;code&gt;sqlite&lt;/code&gt;
database, so there are some answers that are easy to get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; llm logs status
Logging is ON for all prompts
Found log database at /home/anarcat/.config/io.datasette.llm/logs.db
Number of threads logged:   7
Number of turns logged:     12
Number of legacy conversations: 543
Number of legacy responses: 970
Database file size:         9.61MB
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is 10MB of logs, with about a thousand prompts.&lt;/p&gt;

&lt;p&gt;My logs go back to 2024-03-07, a little over two years ago, and
include a mix of Anthropic and OpenAI responses. I used it more in
2024 than 2025, and if the trend continues, I will have used it less
in 2026 again:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; llm logs list -n 0  --json | jq -r .[].datetime_utc | sed &#39;s/-.*//&#39; | sort | uniq -c 
    527 2024
    357 2025
     98 2026
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It looks like about 10 prompts per month right now, down from a peak
of about 60 per month in 2024. It&#39;s pretty difficult to analyze those
actual logs to get more patterns and I won&#39;t run the prompts through a
model &lt;em&gt;again&lt;/em&gt; to process them.&lt;/p&gt;

&lt;h2 id=&quot;how-im-using-models-now&quot;&gt;How I&#39;m using models now&lt;/h2&gt;

&lt;p&gt;At first, I was using it partly for benchmarking model&#39;s capabilities,
like &lt;a href=&quot;https://simonwillison.net/&quot;&gt;Simon Willison&lt;/a&gt; does with his pelicans, clearly not trusting
its output. But I was impressed by the capacities of the Claude Opus
4.5 model when it &lt;a href=&quot;https://gitlab.com/anarcat/scripts/-/blob/main/transmodify.py?ref_type=heads&quot;&gt;wrote this script in January&lt;/a&gt;. Impressed, but
also scared: it&#39;s the first time I felt I could delegate the entirety
of my programming to a model. Just run the code, if it works, it
works, right?&lt;/p&gt;

&lt;p&gt;So what do I use it now? As an example, here are the 10 last prompts
in my history:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;there is now Claude 5, and a fable model, maybe you know about it?&lt;/li&gt;
&lt;li&gt;impress me&lt;/li&gt;
&lt;li&gt;not impressive, i already know all of this&lt;/li&gt;
&lt;li&gt;chat&lt;/li&gt;
&lt;li&gt;in postfix, i have a 300k mailing that happens regularly here. normally, it delivers within about...&lt;/li&gt;
&lt;li&gt;is there a way i could have drained the maildrop queue faster without removing the milter?&lt;/li&gt;
&lt;li&gt;the problem was that rspamd was timing out on the FUZZY_CALLBACK check. how do i disable that?&lt;/li&gt;
&lt;li&gt;how do i disable all spam checks? i just want rspamd to add dkim signatures&lt;/li&gt;
&lt;li&gt;how do the default_destination_concurrency_limit and initial_destination_concurrency settings int...&lt;/li&gt;
&lt;li&gt;mic check&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The first one was me trying to confirm which model I am using, which
is not always obvious when going through the whole &lt;code&gt;llm&lt;/code&gt; stack I&#39;ve
been using. The following two are an attempt at seeing what the model
is capable of and I was &quot;not impressed&quot;, to which Claude answered that
I have a &quot;high bar&quot;, which, fair enough.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;chat&lt;/code&gt; is me failing to use a command line, which shows that
perhaps I need to readjust that &quot;high bar&quot;, again.&lt;/p&gt;

&lt;p&gt;The next five are a rather embarrassing debacle in a large Postfix
mailing that went sideways, and where I couldn&#39;t find an actual
Postfix expert of my level to help. The fabled Claude Fable 5 answered
rather correctly, but dangerously, that I could empty the queue by
disabling the &lt;code&gt;non_smtpd_milters&lt;/code&gt;. What Fable (and myself) did not
realize is that the milter was also adding DKIM signatures, so while the
mailing was expedited, it was done without those precious signatures,
which got us promptly blocked at Gmail. We have recovered since, and,
thanks to the model and reading the &lt;a href=&quot;https://www.postfix.org/pickup.8.html&quot;&gt;Postfix manual&lt;/a&gt; for the
hundredth time, that &lt;a href=&quot;https://www.postfix.org/pickup.8.html&quot;&gt;pickup(8)&lt;/a&gt; is single-threaded and that we
needed to review the architecture of that mailing (and our spam
filters) a bit. Many tickets ensued.&lt;/p&gt;

&lt;p&gt;The last one is a test I did to make sure my last uploads of
&lt;code&gt;llm-anthropic&lt;/code&gt; and its dependency worked correctly.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Note that the above excludes 5 questions I asked Anthropic while
writing this article, where I asked for synonyms and &quot;what nanometer
scale are arduino processors built from? how is an arduino CPU
printed?&quot;, a question which Wikipedia furiously evades providing a
good answer.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Those prompts are pretty typical of my LLM use: I&#39;m testing the models
to see if they work at all, but also, out of desperation, I fire off a
prompt after I fire off questions to colleagues or search engines (in
that order). It&#39;s often weird edge cases like the Prometheus query
language, Python&#39;s matplotlib, LaTeX, Elisp, optimizations, and so on.&lt;/p&gt;

&lt;p&gt;I use models for translation a lot. Being fully bilingual, it is
common for me to think of a word in French or English and fail to find
exactly the right word for that in the other language. Models help
with that, and are also useful to find synonyms. Those are low-token
uses that seem pretty innocuous to me, but I realize the irony of this
after writing about the &lt;a href=&quot;https://anarc.at/blog/2026-05-16-four-horsemen/#the-tower-of-babel&quot;&gt;tower of
Babel&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-i-am-not-using-models-for&quot;&gt;What I am not using models for&lt;/h2&gt;

&lt;p&gt;I am not using models to write prose.&lt;/p&gt;

&lt;p&gt;I am not using models to &lt;em&gt;read&lt;/em&gt; prose. If it&#39;s generated with LLMs, I
stop reading.&lt;/p&gt;

&lt;p&gt;I am not using models to write code, with the exception of that single
Python script above.&lt;/p&gt;

&lt;p&gt;I am generally not using models to &lt;em&gt;review&lt;/em&gt; code, with exceptions. If
I get stuck on a hard problem, I might feed a piece of code to the
model. I repeatedly fed &lt;a href=&quot;https://gitlab.com/anarcat/asncounter/&quot;&gt;&lt;code&gt;asncounter&lt;/code&gt;&lt;/a&gt; into Claude to try to fix a
performance regression I had introduced. It found micro-optimizations
that taught me a thing or two about Python&#39;s internal implementations,
but overall, it was mostly a waste of time. This was in June 2025, so
perhaps now models would fare better. I have not tried again.&lt;/p&gt;

&lt;p&gt;I am not using LLMs to do Debian packaging. When I can, I manually
review the diffs of packages I upload into Debian, still, by hand.&lt;/p&gt;

&lt;p&gt;I do this for the reasons outlined in &lt;a href=&quot;https://anarc.at/blog/2026-05-16-four-horsemen/&quot;&gt;The Four Horsemen of the LLM
Apocalypse&lt;/a&gt;, because I refuse to be
complicit in the:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;aggressive and illegal scraping of the servers I steward&lt;/li&gt;
&lt;li&gt;world-wide computer hardware shortage (making it, by the way,
nearly impossible to run presumably clean local models) and the
attack on our job conditions (also discussed in
&lt;a href=&quot;https://anarc.at/blog/2026-08-18-people-vs-ai-overlords/&quot;&gt;The people vs the AI overlords&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;death of copyright and free software&lt;/li&gt;
&lt;li&gt;complication and enshifitication of everything, and the
destruction of our communities&lt;/li&gt;
&lt;li&gt;the imperialist &lt;a href=&quot;https://www.thenerdreich.com/&quot;&gt;Nerd Reich&lt;/a&gt; that wants to take over the world&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Like I reluctantly use Intel computers, I &lt;em&gt;do&lt;/em&gt; fire off a prompt. But
I still hold on to the dream that we can build &lt;a href=&quot;https://en.wikipedia.org/wiki/Community_of_practice&quot;&gt;communities of
practice&lt;/a&gt; that hold human knowledge collectively and not &lt;a href=&quot;https://gizmodo.com/sam-altman-says-intelligence-will-be-a-utility-and-hes-just-the-man-to-collect-the-bills-2000732953&quot;&gt;offload
that as a utility&lt;/a&gt; to some megalomaniac billionaire.&lt;/p&gt;

&lt;h1 id=&quot;their-llm-use-i-am-forced-into&quot;&gt;Their LLM use I am forced into&lt;/h1&gt;

&lt;p&gt;So that&#39;s me. Clearly, I&#39;m going against the grain here. Everywhere I
look, I see LLM-generated code and projects. Slop and botnets have
flooded the web.&lt;/p&gt;

&lt;p&gt;I use &lt;a href=&quot;https://wadamesh.com/&quot;&gt;Wadamesh&lt;/a&gt;, clearly &lt;a href=&quot;https://github.com/ALLFATHER-BV/wadamesh/graphs/contributors?from=2026-05-23&quot;&gt;vibe-coded&lt;/a&gt;, because it&#39;s the best
graphical interface for MeshCore that runs on portable devices. I wish
it was made by a human, in a community I could participate in, but it
isn&#39;t, and I don&#39;t.&lt;/p&gt;

&lt;p&gt;I package the above &lt;code&gt;llm&lt;/code&gt; toolset, which is &lt;a href=&quot;https://simonwillison.net/2026/Aug/24/llm-anthropic/&quot;&gt;more and more
vibe-coded&lt;/a&gt;, but I still review the diffs. And I have to say: I
trust Simon here. The code is verbose as hell, feels overengineered,
and &lt;code&gt;llm&lt;/code&gt; feels slow, but it generally works, and Simon is still at
the gate.&lt;/p&gt;

&lt;p&gt;The Anthropic SDK is another thing entirely. The &lt;a href=&quot;https://salsa.debian.org/python-team/packages/anthropic-sdk-python/-/commit/a3087b3cef63ae239a1f558a6b46565ce0485b7d&quot;&gt;0.91.0 to 0.120
upload&lt;/a&gt;, for example, was nuts:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; 806 files changed, 72281 insertions(+), 1478 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I explicitly did not review that entire diff. It feels like there&#39;s a
lot of garbage there to just have a shim between a proprietary API and
Python. But this is the hand I&#39;ve been dealt.&lt;/p&gt;

&lt;h1 id=&quot;larger-projects-llm-use&quot;&gt;Larger projects LLM use&lt;/h1&gt;

&lt;p&gt;LLMs are being used in the Linux kernel, Firefox, &lt;code&gt;rsync&lt;/code&gt;, Rust, and
other places. I don&#39;t feel good about this, particularly in Rust, but
they at least made a decent &lt;a href=&quot;https://forge.rust-lang.org/policies/llm-usage.html&quot;&gt;policy&lt;/a&gt;. I am glad GCC made a &lt;a href=&quot;https://lwn.net/Articles/1086041/&quot;&gt;policy
against LLM contributions&lt;/a&gt; and I support the &lt;a href=&quot;https://human-emacs.org/&quot;&gt;human Emacs&lt;/a&gt;
project.&lt;/p&gt;

&lt;p&gt;We need to have a set of foundational tools that are &quot;clean&quot; in the
sense that they are built upon a community of people that understand
how they are built.&lt;/p&gt;

&lt;p&gt;Maybe that&#39;s naive or even impossible. The Linux kernel and GCC, in
particular, are massive projects that have long grown past the scale
of a single person&#39;s understanding. But the theory was that a
&lt;em&gt;community&lt;/em&gt; of humans can understand &lt;em&gt;collectively&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now we seem to be throwing up our hands and giving up on
that community. That LLMs will just fix the problem, whatever it
is. But we&#39;re all just one rug pull away from being completely
incapable of managing those projects. The argument there is that we&#39;ll
just switch to local models, but no one is actually doing that.
All I see is people use local models &lt;a href=&quot;https://micahflee.com/agentic-coding-techniques/&quot;&gt;as a corner case&lt;/a&gt;
(for privacy) or as in &lt;a href=&quot;https://changelog.complete.org/archives/44740-ai-in-debian-the-vote-proposals-and-nuance&quot;&gt;theory&lt;/a&gt;, but in reality, everyone uses the
centralized frontier models right now. We just can&#39;t fallback.&lt;/p&gt;

&lt;p&gt;We&#39;re in the same situation we were, a decade or two ago, when
Microsoft decided it would kill free office alternatives by making
Office free for non-profits. It worked: thousands, if not millions of
schools, community groups and individuals stopped looking for
alternatives (including free software but also &quot;piracy&quot;) for Office
and embraced what seemed like a generous offer.&lt;/p&gt;

&lt;p&gt;Now Microsoft pulled the plug and &lt;a href=&quot;https://slate.com/technology/2026/08/microsoft-software-nonprofit-data-delete.html&quot;&gt;Over 170,000 Nonprofits Lost All
Their Data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&#39;m afraid the rug pull on LLMs will be much worse: never mind that
Linus won&#39;t be able to use his &lt;a href=&quot;https://github.com/torvalds/linux/commit/818bebeb63dd6bf5f4e07e145f6cdbace520a34c&quot;&gt;tireless helper&lt;/a&gt; to fix obscure kernel
bugs; we&#39;re looking at a collapse of the economy so large that we are
already &lt;a href=&quot;https://prospect.org/2026/08/03/ai-bailout-could-be-baked-into-bubble-private-equity-life-insurers-loans/&quot;&gt;talking about bailing out the companies responsible&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In a sense, the most striking thing about the Debian vote is it has
actually no option to completely refuse upstream LLM contributions. It
seems the community has taken it for granted that it&#39;s now impossible
to build Debian entirely without LLMs. We lost the battle even without
a fight, it seems.&lt;/p&gt;

&lt;h1 id=&quot;a-plea-for-small&quot;&gt;A plea for small&lt;/h1&gt;

&lt;p&gt;If it has really become impossible for us to manage the complexity we
have built, maybe it&#39;s time to stop and think about what we&#39;re doing
in the first place. We&#39;re struggling to even &lt;a href=&quot;https://bootstrappable.org/&quot;&gt;bootstrap&lt;/a&gt; our
current toolchain!&lt;/p&gt;

&lt;p&gt;This is one of the things I like the most about working on the mesh:
it&#39;s low tech, small Arduino devices that is built with decades-old
&lt;a href=&quot;https://en.wikipedia.org/wiki/Semiconductor_device_fabrication&quot;&gt;semiconductor processes&lt;/a&gt; that is understandable by human
beings.&lt;/p&gt;

&lt;p&gt;Maybe the answer lies more in single-purpose devices like those
communicators and simpler multi-purpose computers than what we have
now, which is what the &lt;a href=&quot;https://en.wikipedia.org/wiki/Permacomputing&quot;&gt;permacomputing&lt;/a&gt; movement is about.&lt;/p&gt;

&lt;p&gt;Small is beautiful, let&#39;s scale it down.&lt;/p&gt;





&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn:1&quot;&gt;
and yes, I&#39;m sorry this has gotten this long, I hope you will
forgive those 3000 words.&lt;a href=&quot;https://anarc.at/tag/debian-planet/#fnref:1&quot; rev=&quot;footnote&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt; </description> 
	<pubDate>Thu, 27 Aug 2026 14:10:43 +0000</pubDate>

</item> 
<item>
	<title>Gunnar Wolf: As far as LLMs go in Debian, I think that 936241857</title>
	<guid>https://gwolf.org/2026/08/as-far-as-llms-go-in-debian-i-think-that-936241857.html</guid>
	<link>https://gwolf.org/2026/08/as-far-as-llms-go-in-debian-i-think-that-936241857.html</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/gwolf.png&quot; width=&quot;69&quot; height=&quot;83&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;p&gt;I believe that, in the context of Debian voting, we are better off when we
know the opinion of our peers, however, since &lt;a href=&quot;https://www.debian.org/vote/2022/vote_001&quot;&gt;the 2022-001
vote&lt;/a&gt;, it is no longer the
case. Still, some DDs have disclosed the way they are voting on &lt;a href=&quot;https://www.debian.org/vote/2026/vote_002&quot;&gt;the
2026-002 General Resolution currently in progress, regarding LLM usage in
Debian&lt;/a&gt;. So, here goes my vote
and reasoning as briefly as possible. This is the ballot I sent to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;devotee&lt;/code&gt;, the &lt;em&gt;Debian Vote Engine&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-=-=-=-=-=- Don&#39;t Delete Anything Between These Lines =-=-=-=-=-=-=-=-
d69f9187-ed2f-40b6-a2eb-4211d3f84d86
[9] Choice 1: Ban LLM contributions from Debian via Social Contract
[3] Choice 2: Allow AI-Assisted Contributions with conditions
[6] Choice 3: Reject LLMs as far as practical, update Code of Conduct
[2] Choice 4: Accept AI contributions for Debian specific work
[4] Choice 5: Responsible Use of Generative AI
[1] Choice 6: A cautious approach to generative AI
[8] Choice 7: Debian is created by humans
[5] Choice 8: Avoid the use of LLM: climate destruction is a deal breaker
[7] Choice 9: None of the above
-=-=-=-=-=- Don&#39;t Delete Anything Between These Lines =-=-=-=-=-=-=-=-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the first time I can recall I delay my voting until after receiving
the &lt;em&gt;final call for votes&lt;/em&gt; (the vote will be over two days from now). I had
some participation in the discussion, so I guess my position will be of no
big surprise to anybody. I was also a &lt;em&gt;seconder&lt;/em&gt; for choices D and F (4 and
6 in the vote text). This does not &lt;em&gt;necessarily&lt;/em&gt; mean I believe they are
the best (although I did rank them as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, meaning I do): sometimes
you agree a given text &lt;em&gt;needs to be&lt;/em&gt; in the ballot, and &lt;em&gt;second&lt;/em&gt; it even
though you don’t intend to vote for it.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;LLM?&quot; src=&quot;https://gwolf.org/files/2026-08/llm-quest.200.png&quot; title=&quot;LLM?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ranking this ballot was &lt;strong&gt;a mess&lt;/strong&gt; due to the complex array of options it
encodes. I warmly thank Lucas Nussbaum for coming up with the &lt;a href=&quot;https://people.debian.org/~lucas/gr-2026-002/comparison.html#ballot=936241857&quot;&gt;LLM usage in
Debian: ballot option
comparison&lt;/a&gt;
(URL shown with my particular ballot ordering).&lt;/p&gt;

&lt;p&gt;How do you read a complex Debian ballot like this one? I rank with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[1]&lt;/code&gt; my
favorite option, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[2]&lt;/code&gt; for the next one, etc. We &lt;em&gt;can&lt;/em&gt; encode options to be
tied (i.e. setting more than options to the same value), and we can
implicitly &lt;em&gt;push&lt;/em&gt; options to the worst position by leaving them blank (so,
with&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ ]&lt;/code&gt;); I chose not to do any of those.&lt;/p&gt;

&lt;p&gt;What were my voting guidelines?&lt;/p&gt;

&lt;p&gt;First, I don’t want anything &lt;em&gt;banning&lt;/em&gt; or that &lt;em&gt;threatens with disciplinary
action,&lt;/em&gt; so I push them below the special &lt;em&gt;none of the above&lt;/em&gt;
marker. Second… Some time ago I published a review in my blog (and in
Computing Reviews) about &lt;a href=&quot;https://gwolf.org/2026/04/heads-we-win-tails-you-lose-ai-detectors-in-education.html&quot;&gt;the unfeasibility and unfairness of detecting LLM
output on students’
assignments&lt;/a&gt;. I
strongly believe we ought to appeal to the human responsibility and
professionalism in all Debian contributors. This is the reason I proposed
this amendment paragraph, that was accepted in choice F (6), which I ranked
as my favorite:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;The Debian project has always recognized the commitment and
professionalism of its members. All contributions are under the
responsibility of the Debian Contributor making it, no matter the
technology they have behind. We trust all Debian Developers,
Maintainers and Contributors will continue to uphold the high quality
values that have distinguished our project from its onset.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Other than that… I do not consider myself to be in any way an LLM
&lt;em&gt;fanboy&lt;/em&gt; nor anything like that. I distrust and dislike the excessive use
of this technology, and continue to warn about the dangers and bad points
of its abuse. But in my day-to-day professional work, I am also starting to
rely on it for &lt;em&gt;some&lt;/em&gt; tasks. I recognize it &lt;em&gt;needs&lt;/em&gt; a lot of human
oversight and… lets call it &lt;em&gt;hand-holding&lt;/em&gt; to produce anything worth
it, at least in my experience. But I do benefit from it — and &lt;strong&gt;always
disclose its use&lt;/strong&gt; to people who might be affected by it. I would like
Debian to adopt such a stance.&lt;/p&gt;

&lt;p&gt;Of course, I recgnize proposal &lt;em&gt;H/8&lt;/em&gt; as important (&lt;em&gt;Avoid the use of LLM:
climate destruction is a deal breaker&lt;/em&gt;). Some people have argued it’s not
bad &lt;em&gt;at all&lt;/em&gt;. I do not buy such claims: LLMs are &lt;em&gt;f*cking expensive&lt;/em&gt; to
train. But training can be seen as a once-per-model cost, and &lt;em&gt;fine-tuning&lt;/em&gt;
a good model to be run locally can be really worth it. It still pains me
somewhat, but I cannot push this option higher than its #5 position in my
list.&lt;/p&gt; </description> 
	<pubDate>Thu, 27 Aug 2026 00:48:32 +0000</pubDate>

</item> 
<item>
	<title>Ritesh Raj Sarraf: Taming the AI Agents (Part 2): Cross-Vendor Agent-to-Agent (A2A) Swarms over the Software Forge</title>
	<guid>https://researchut.com/blog/taming_the_ai_agents_part_2_a2a/</guid>
	<link>https://researchut.com/blog/taming_the_ai_agents_part_2_a2a/</link>
     <description>  &lt;img src=&quot;http://planet.debian.org/heads/rrs.png&quot; width=&quot;75&quot; height=&quot;80&quot; alt=&quot;&quot; align=&quot;right&quot; style=&quot;float: right;&quot;&gt;  &lt;h2 id=&quot;preface-the-unanswered-frontier&quot;&gt;Preface: The Unanswered Frontier&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&quot;https://www.researchut.com/blog/taming_the_ai_agents&quot;&gt;Part 1: Taming the AI Agents&lt;/a&gt;, I shared the architectural blueprint of &lt;strong&gt;CAMP (Cross-Agent Memory Protocol)&lt;/strong&gt;—how we used Linux Bubblewrap (&lt;code&gt;bwrap&lt;/code&gt;), &lt;code&gt;camp-acpd&lt;/code&gt;, OPA policy enforcement, and a central &lt;code&gt;pgvector&lt;/code&gt; MemPalace to bring deterministic discipline, sandboxing, and long-term memory to a heterogeneous fleet of AI coding assistants (Claude Code, Google Antigravity, Grok Build, and GitHub Copilot).&lt;/p&gt;
&lt;p&gt;At the end of that article, however, I highlighted a significant hurdle: &lt;strong&gt;The Headless Limitation&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“While passive A2A works beautifully for structured handoffs, the current frontier of agentic design faces a key limitation: agents are not yet fully headless-capable. They depend on the active terminal session, browser loop, or prompt loop of the user to keep executing. Because agents cannot run completely detached in the background as daemon processes, we cannot yet achieve active A2A communication…”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For weeks, this seemed like an insurmountable impasse. Proprietary AI vendors have zero commercial incentive to ratify a universal, open, cross-vendor Agent-to-Agent (A2A) communication protocol. Each vendor builds its own walled garden (Claude’s cross-session features, OpenAI’s custom ecosystems, etc.). If you wait for the industry to hand you an open interoperability standard, you will wait forever.&lt;/p&gt;
&lt;p&gt;Then, on August 26, 2026, inspired by Colin Walters’ article on &lt;a href=&quot;https://blog.verbum.org/2026/08/21/agentic-ai-and-software-forges/&quot;&gt;&lt;em&gt;Agentic AI and software forges&lt;/em&gt;&lt;/a&gt; and GitHub Agentic Workflows (&lt;code&gt;gh-aw&lt;/code&gt;), we had a sudden realization:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We don’t need a new protocol, a new distributed message broker, or permission from proprietary AI vendors. We already have the universal, decentralized communication bus that software engineers have relied on for decades: the software forge itself.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Over the span of 48 intensive hours (from RFC &lt;a href=&quot;http://localhost:8095/CAMP/camp-infrastructure/issues/788&quot;&gt;#788&lt;/a&gt; through milestones M1 to M3 and live dogfooding on &lt;a href=&quot;http://localhost:8095/CAMP/camp-infrastructure/issues/813&quot;&gt;#813&lt;/a&gt;), we designed, implemented, fortified, and verified fully autonomous, headless, cross-vendor Agent-to-Agent swarms running over a local &lt;strong&gt;Gitea&lt;/strong&gt; forge.&lt;/p&gt;
&lt;p&gt;Here is how we did it, the architectural hurdles we solved, and why this changes the game for autonomous software engineering.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;1-the-core-realization-the-forge-is-the-bus&quot;&gt;1. The Core Realization: The Forge is the Bus&lt;/h2&gt;
&lt;p&gt;When people think about multi-agent swarms, they often imagine complex distributed RPC frameworks, microservices exchanging ephemeral JSON-RPC blobs, or bespoke socket daemons.&lt;/p&gt;
&lt;p&gt;In practice, this approach suffers from major flaws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No shared context or durable audit trail:&lt;/strong&gt; Transient network packets vanish unless heavily logged.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proprietary CLI fragmentation:&lt;/strong&gt; Different vendor tools (Claude CLI, Antigravity CLI, Grok CLI, Copilot CLI) do not speak the same internal language.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loss of human visibility:&lt;/strong&gt; When agents talk over private network channels, human operators lose the ability to inspect, pause, or audit the conversation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By flipping the paradigm and making &lt;strong&gt;the software forge (Gitea)&lt;/strong&gt; the primary communication channel, everything falls naturally into place:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Issues and Pull Requests are the shared state:&lt;/strong&gt; The issue description and discussion thread form the canonical, append-only conversation log.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;@mentions&lt;/code&gt; are the dispatch triggers:&lt;/strong&gt; When an agent (or human) writes &lt;code&gt;@grok Please review this PR&lt;/code&gt; in a comment, Gitea fires a standard webhook (&lt;code&gt;issue_comment&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Webhooks provide unforgeable authentication:&lt;/strong&gt; The webhook payload contains the cryptographically verified sender identity. An agent cannot spoof another agent’s identity by merely typing their name in text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Every CLI already supports non-interactive prompt mode:&lt;/strong&gt; The CLIs don’t even agree on the command-line flag—Claude uses &lt;code&gt;-p&lt;/code&gt;, Grok uses &lt;code&gt;-p&lt;/code&gt;, Antigravity uses &lt;code&gt;--print&lt;/code&gt;, Copilot uses &lt;code&gt;--prompt&lt;/code&gt;. But they all agree on the essential contract: &lt;strong&gt;“Take a prompt string, execute tools, print output, and exit.”&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;┌──────────────┐         Gitea Webhook          ┌──────────────────────┐
│ Gitea Forge  │ ─────────────────────────────&amp;gt; │ camp-a2a-bridge.py   │
│ (localhost)  │  (issue_comment / assignment)  │ (Validates &amp;amp; Files)  │
└──────────────┘                                └──────────┬───────────┘
       ▲                                                   │
       │                                                   ▼
       │ Writes comment / review                ┌──────────────────────┐
       │ via camp_acp_gateway                   │ A2A Inbox Ledger     │
       │                                        └──────────┬───────────┘
┌──────┴──────────────────────┐                            │
│ Fortified Headless Agent    │                            ▼
│ (bwrap + OPA + MCP sandbox) │ &amp;lt;───────────────── ┌──────────────────────┐
│  • Claude Code (-p)         │  Spawn PID         │ camp-a2a-dispatcher  │
│  • Grok Build (-p)          │  (Cold or Resume)  │ (Enforces Hop Cap,   │
│  • Antigravity (--print)    │                    │  Rule 1/2, Sandbox)  │
└─────────────────────────────┘                    └──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h2 id=&quot;2-proving-fortified-headless-execution&quot;&gt;2. Proving Fortified Headless Execution&lt;/h2&gt;
&lt;p&gt;Before opening the floodgates to background agent dispatch, we had to answer a critical security question: &lt;strong&gt;Does a non-interactive, headless agent run with the same strict security sandboxing, audit logging, and tool rails as an interactive session?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On August 26, we probed all fleet launchers on the host with a baseline check:
&lt;code&gt;&#39;Call camp_startup_check and print its result verbatim, then exit.&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The results settled the question immediately:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Antigravity (&lt;code&gt;agy --print&lt;/code&gt; / KIR):&lt;/strong&gt; &lt;strong&gt;PASS&lt;/strong&gt; — Gateway answered, full JSON returned.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grok (&lt;code&gt;grok -p&lt;/code&gt; / GRK):&lt;/strong&gt; &lt;strong&gt;PASS&lt;/strong&gt; — Gateway answered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code (&lt;code&gt;claude -p&lt;/code&gt; / CLD):&lt;/strong&gt; &lt;strong&gt;PASS&lt;/strong&gt; — Gateway answered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Copilot CLI (&lt;code&gt;copilot --prompt&lt;/code&gt; / CPL):&lt;/strong&gt; Initially held on TTY tool consent; later unlocked in Milestone 6 via &lt;code&gt;--allow-all-tools --session-id=&amp;lt;uuid&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Audit Trail:&lt;/strong&gt; Consecutive audit IDs were recorded in the central ledger: &lt;strong&gt;4574 (KIR), 4575 (GRK), 4576 (CLD)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This proved that a headless run through our fortified pilot launcher (&lt;code&gt;camp_pilot_*.sh&lt;/code&gt;) is a &lt;strong&gt;first-class, fully audited, sandboxed CAMP agent&lt;/strong&gt; running inside its Bubblewrap container under OPA policy gates. It is not an unconstrained background script or a degraded bypass.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;3-the-3-tier-memory-architecture&quot;&gt;3. The 3-Tier Memory Architecture&lt;/h2&gt;
&lt;p&gt;A naive multi-agent dispatch has an immediate flaw: &lt;strong&gt;Every time an agent is invoked, it starts from a blank slate (cold start).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;@claude&lt;/code&gt; tags &lt;code&gt;@grok&lt;/code&gt; to review code, and &lt;code&gt;@grok&lt;/code&gt; replies asking for clarification, &lt;code&gt;@claude&lt;/code&gt;’s second invocation would normally forget everything it did 5 minutes ago, forcing it to burn thousands of tokens re-reading the entire git history from scratch.&lt;/p&gt;
&lt;p&gt;To solve this, we established a clean &lt;strong&gt;3-Tier Memory Model&lt;/strong&gt;:&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;┌────────────────────────────────────────────────────────────────────────┐
│                        3-TIER MEMORY MODEL                             │
├────────────────────────────────────────────────────────────────────────┤
│ Tier 1: CLI Conversation Session (Working Memory)                      │
│   • Per-(Agent, Repo, Issue) mapping in a2a-sessions.json              │
│   • Fast, native, compacted context across multi-turn pokes            │
│   • Resumed via --resume (CLD), -r (GRK), --conversation (agy)         │
├────────────────────────────────────────────────────────────────────────┤
│ Tier 2: The Gitea Thread (Public Bus &amp;amp; Record)                         │
│   • Cross-vendor shared truth across Claude, Grok, Antigravity &amp;amp; Human │
│   • Survives process restarts, machine reboots, and dead sessions      │
├────────────────────────────────────────────────────────────────────────┤
│ Tier 3: Central MemPalace (Durable Long-Term Knowledge)                │
│   • pgvector database (17,000+ drawers across agent wings)             │
│   • Structured Knowledge Graph (mempalace_kg_*) for mutable facts      │
│   • Attributed AAAK dialect queryable by any agent across any project  │
└────────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;the-banana-two-shot-test&quot;&gt;The &lt;code&gt;BANANA&lt;/code&gt; Two-Shot Test&lt;/h3&gt;
&lt;p&gt;To verify Tier 1 working memory persistence across independent processes, we designed a simple two-shot host test:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Shot 1 (Create):&lt;/strong&gt; Dispatch agent headlessly: &lt;em&gt;“Remember the token BANANA-M2. Print ok and exit.”&lt;/em&gt; Capture the vendor’s session UUID.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shot 2 (Resume):&lt;/strong&gt; Spawn a completely &lt;strong&gt;new operating system process&lt;/strong&gt; with the resume flag pointing to that UUID: &lt;em&gt;“What token did I ask you to remember?”&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Every agent CLI passed with flying colors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Grok:&lt;/strong&gt; &lt;code&gt;-r 01a03ecc-3ed0-71e1-9a5c-e098bb29ba10&lt;/code&gt; answered &lt;code&gt;BANANA-GRK&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude:&lt;/strong&gt; &lt;code&gt;--resume 0a587733-9aec-43c5-9cb7-d424e95b2c5b&lt;/code&gt; answered &lt;code&gt;BANANA-CLD&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Antigravity:&lt;/strong&gt; &lt;code&gt;--conversation 2e3c43d9-d6fe-4c5c-801b-b9ceb2e7e196&lt;/code&gt; answered &lt;code&gt;BANANA-KIR-JSON&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot:&lt;/strong&gt; &lt;code&gt;--session-id &amp;lt;uuid&amp;gt;&lt;/code&gt; verified in Milestone 6 (DoD #820).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The dispatcher simply maintains a lightweight JSON mapping (&lt;code&gt;(agent, repo, issue_number) -&amp;gt; vendor_session_uuid&lt;/code&gt;). On the first poke of an issue, it creates and saves the session ID; on any subsequent poke on that same issue, it resumes the exact same conversational thread!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;4-the-engineering-milestones-from-concept-to-production&quot;&gt;4. The Engineering Milestones: From Concept to Production&lt;/h2&gt;
&lt;p&gt;Building this system required solving several subtle, real-world friction points across multiple agent CLI implementations. Under the guidance of our plan of record (RFC #788), we delivered this through four focused milestones:&lt;/p&gt;
&lt;h3 id=&quot;milestone-1--11-reliable-headless-spawning&quot;&gt;Milestone 1 &amp;amp; 1.1: Reliable Headless Spawning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR #797 (M1):&lt;/strong&gt; Configured the dispatcher launch table for all probed CLIs with JSON output formatting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR #800 (M1.1):&lt;/strong&gt; &lt;strong&gt;Eliminated the “queue-behind-live-session” anti-pattern.&lt;/strong&gt; Originally, if a human had a Claude or Grok TUI open on their desktop, the dispatcher would defer incoming tasks so as not to collide with the live session. We realized that headless tasks must be independent: every Gitea mention spawns an isolated, sandboxed background process tied to that specific issue, allowing concurrent headless work while the human works in their interactive TUI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR #803 (M1.2):&lt;/strong&gt; Standardized command-line argument parsing for Antigravity (&lt;code&gt;agy --print &amp;lt;prompt&amp;gt; --output-format json&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;milestone-2-session-per-issue-working-memory&quot;&gt;Milestone 2: Session-per-Issue Working Memory&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR #805 (M2):&lt;/strong&gt; Implemented &lt;code&gt;a2a-sessions.json&lt;/code&gt; to store and resume vendor session UUIDs. If a resume fails (e.g. session purged upstream), the dispatcher gracefully falls back to a clean cold start without failing the task.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;milestone-3-cross-agent-hops--crucial-safety-rails&quot;&gt;Milestone 3: Cross-Agent Hops &amp;amp; Crucial Safety Rails&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR #807 (M3):&lt;/strong&gt; Enabled agent-to-agent dispatch (Rule 2 reversal). Previously, only mentions authored by &lt;code&gt;rrs&lt;/code&gt; (the human) would trigger execution. With M3, an authenticated comment from &lt;code&gt;@claude&lt;/code&gt; mentioning &lt;code&gt;@grok&lt;/code&gt; triggers Grok’s headless launcher.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR #811 (M3.1):&lt;/strong&gt; Set &lt;code&gt;--permission-mode bypassPermissions&lt;/code&gt; for headless Claude Code so non-interactive runs execute tool calls without stalling on TTY prompts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR #812 (M3.2):&lt;/strong&gt; Restricted agent summon parsing to line-initial &lt;code&gt;@login&lt;/code&gt; tokens with a non-empty task description (#810), preventing accidental dispatches from passive conversational references.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;milestone-4-directives-specification--living-documentation&quot;&gt;Milestone 4: Directives, Specification &amp;amp; Living Documentation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR #815 (M4):&lt;/strong&gt; Aligned CAMP fleet directives, architecture specifications, and user documentation with the live A2A implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;milestone-5-concurrent-dispatching--hop-cap-attribution&quot;&gt;Milestone 5: Concurrent Dispatching &amp;amp; Hop-Cap Attribution&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR #816:&lt;/strong&gt; Stamped hop-cap notices under a dedicated system bridge identity and automatically applied the &lt;code&gt;needs-human&lt;/code&gt; label on held threads.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR #817 (Threaded Scheduler):&lt;/strong&gt; Replaced the single-threaded serial dispatcher with a concurrent thread-pool scheduler (#804). Multi-agent dispatches across different issues now execute concurrently in parallel background threads instead of queuing behind long-running tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;milestone-6-full-fleet-coverage-with-github-copilot&quot;&gt;Milestone 6: Full Fleet Coverage with GitHub Copilot&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR #819 (M6):&lt;/strong&gt; Brought GitHub Copilot CLI into the headless A2A fleet (#818). By passing &lt;code&gt;--allow-all-tools&lt;/code&gt; and pinning minted session UUIDs (&lt;code&gt;--session-id=&amp;lt;uuid&amp;gt;&lt;/code&gt;), Copilot achieved full parity with Claude, Grok, and Antigravity, completing 100% headless fleet coverage across all four major AI coding assistants.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;5-hard-safety-rails-preventing-autonomous-runaway-loops&quot;&gt;5. Hard Safety Rails: Preventing Autonomous Runaway Loops&lt;/h2&gt;
&lt;p&gt;Letting AI agents autonomously invoke each other in background loops without a human watching is a recipe for an infinite, credit-draining token fire. We put four non-negotiable safety guardrails in place:&lt;/p&gt;
&lt;h3 id=&quot;guardrail-1-the-strict-hop-cap&quot;&gt;Guardrail 1: The Strict Hop Cap&lt;/h3&gt;
&lt;p&gt;The dispatcher tracks &lt;code&gt;hops&lt;/code&gt; per &lt;code&gt;(repo, issue)&lt;/code&gt;. Each agent-to-agent dispatch increments the counter.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hop Limit = 3:&lt;/strong&gt; A typical review round-trip is 2 hops (Human $\rightarrow$ Claude $\rightarrow$ Grok $\rightarrow$ Claude).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic Halt on Hop 4:&lt;/strong&gt; If agents attempt a 4th autonomous hop without human participation, the bridge refuses to launch, posts a diagnostic notice to the thread:
&lt;code&gt;[camp-a2a-bridge] hop cap reached (3 agent-to-agent dispatches on CAMP/camp-infrastructure#813) — not launching GRK for claude&#39;s mention&lt;/code&gt;,
and holds execution until the human (&lt;code&gt;rrs&lt;/code&gt;) provides input or resets the count.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;[ Human: rrs ] ────── (Cold Start) ─────&amp;gt; [ @Claude ]
                                               │
                                       (Hop 1) │ @grok please review
                                               ▼
                                          [ @Grok ]
                                               │
                       (Hop 2: Resume)         │ @claude I reviewed
                                               ▼
                                         [ @Claude ]
                                               │
                                       (Hop 3) │ @grok ack hop 4
                                               ▼
                                  ┌─────────────────────────┐
                                  │  DISPATCHER HOP CAP: 3  │
                                  │   *** BLOCKED &amp;amp; HELD ***│
                                  │   Awaiting Human Reset  │
                                  └─────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;guardrail-2-deliberate-summon-parsing-m32-810--pr-812&quot;&gt;Guardrail 2: Deliberate Summon Parsing (M3.2, #810 / PR #812)&lt;/h3&gt;
&lt;p&gt;In human conversation, we often reference colleagues in passing: &lt;em&gt;“I will talk to @claude about this later”&lt;/em&gt; or &lt;em&gt;“See @grok’s table above”&lt;/em&gt;.
Early prototypes treated any appearance of &lt;code&gt;@agent&lt;/code&gt; as a dispatch trigger, causing accidental, unwanted agent launches!&lt;/p&gt;
&lt;p&gt;We instituted a strict &lt;strong&gt;Summon Predicate&lt;/strong&gt;:
For fleet agents, a mention is only considered an actionable summon if:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;@login&lt;/code&gt; appears as the &lt;strong&gt;starting word of a line&lt;/strong&gt; (optionally preceded by markdown list markers &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, or &lt;code&gt;&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It is immediately followed by whitespace and a non-empty &lt;strong&gt;task description&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Mid-sentence mentions in discussion paragraphs are parsed as passive conversational text and never trigger background dispatches.&lt;/p&gt;
&lt;h3 id=&quot;guardrail-3-headless-tool-permissions-without-weakening-security-m31-809--pr-811&quot;&gt;Guardrail 3: Headless Tool Permissions without Weakening Security (M3.1, #809 / PR #811)&lt;/h3&gt;
&lt;p&gt;In interactive mode, Claude Code presents interactive TTY prompts asking the user to approve MCP tool calls (such as &lt;code&gt;camp_pr_get&lt;/code&gt; or &lt;code&gt;camp_pr_get_diff&lt;/code&gt;). In unattended headless mode, there is no TTY, causing the run to fail with permission errors.&lt;/p&gt;
&lt;p&gt;To fix this, we configured &lt;code&gt;--permission-mode bypassPermissions&lt;/code&gt; for Claude’s headless CLI invocation. Crucially, &lt;strong&gt;this only bypasses Claude’s internal TTY UI prompt—it does not bypass CAMP’s security rails&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;All command executions still route through &lt;code&gt;camp-acpd&lt;/code&gt; and Bubblewrap namespaces; OPA policy checks remain active; and privileged operations (such as merging pull requests or restarting system services) still trigger desktop &lt;strong&gt;Zenity HITL dialogs&lt;/strong&gt; on the human’s workstation.&lt;/p&gt;
&lt;h3 id=&quot;guardrail-4-the-sovereign-kill-switch-rule-1&quot;&gt;Guardrail 4: The Sovereign Kill Switch (Rule 1)&lt;/h3&gt;
&lt;p&gt;At any point, the human operator can instantly freeze all background agent dispatches across the entire infrastructure with a single standard Linux command:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span style=&quot;display: flex;&quot;&gt;&lt;span&gt;systemctl --user stop camp-a2a-active.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr /&gt;
&lt;h2 id=&quot;6-live-dogfooding-watching-the-swarm-in-action&quot;&gt;6. Live Dogfooding: Watching the Swarm in Action&lt;/h2&gt;
&lt;p&gt;On August 27, 2026, on issue &lt;a href=&quot;http://localhost:8095/CAMP/camp-infrastructure/issues/813&quot;&gt;CAMP/camp-infrastructure#813&lt;/a&gt;, we ran the full live dogfood test of the A2A system.&lt;/p&gt;
&lt;p&gt;Here is the exact transcript of what took place entirely autonomously in the Gitea issue thread:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Human initiates:&lt;/strong&gt; &lt;code&gt;rrs&lt;/code&gt; comments on issue #813:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;@claude Please start the M3 dogfood. On this issue, post a conversation comment whose first line is exactly: @grok Please review this issue in one short paragraph, then stop.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Claude launches (Cold start):&lt;/strong&gt; The dispatcher spins up &lt;code&gt;@claude&lt;/code&gt; headlessly inside &lt;code&gt;bwrap&lt;/code&gt;. Claude reads the issue and posts:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;@grok Please review this issue in one short paragraph, then stop.&lt;/code&gt;&lt;br /&gt;
&lt;em&gt;(M3 dogfood step 2 — posted by @claude on rrs’s instruction; this is the CLD $\rightarrow$ GRK fleet hop.)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Grok launches (Cold start, Hop 1):&lt;/strong&gt; The bridge intercepts Claude’s comment, identifies the start-of-line &lt;code&gt;@grok&lt;/code&gt; summon, and launches &lt;code&gt;@grok&lt;/code&gt;. Grok reviews the issue and replies:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;@claude I have reviewed this issue. Please confirm and stop.&lt;/code&gt;&lt;br /&gt;
&lt;em&gt;#813 is a throwaway live dogfood of A2A M3 on 6.git+b78c65cf…&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Claude resumes (Session Resume, Hop 2):&lt;/strong&gt; The bridge intercepts Grok’s comment, sees the &lt;code&gt;@claude&lt;/code&gt; summon, and launches Claude with &lt;code&gt;--resume b398d048-ccc3-4cce-8437-4cf8748881a8&lt;/code&gt;. Claude immediately remembers its earlier context without token waste:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Confirmed — Grok&#39;s review (comment 88562) received via the GRK→CLD fleet hop. That completes the round trip: rrs→CLD, CLD→GRK, GRK→CLD, and this reply. I am deliberately not tagging anyone here, so the chain stops at two agent hops. Stopping.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing the Hop Cap (Hop 3 $\rightarrow$ 4):&lt;/strong&gt;
&lt;code&gt;grok&lt;/code&gt; prompts &lt;code&gt;@claude Please ack hop four then stop.&lt;/code&gt; Claude posts &lt;code&gt;@grok Please ack hop four then stop.&lt;/code&gt; (Hop 3).
When Grok would have been launched for Hop 4, the dispatcher intervenes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;[camp-a2a-bridge] hop cap reached (3 agent-to-agent dispatches on CAMP/camp-infrastructure#813) — not launching GRK for claude&#39;s mention.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Human Reset &amp;amp; Multi-Agent Wrap-up:&lt;/strong&gt;
&lt;code&gt;rrs&lt;/code&gt; steps in, resets the state, and asks the fleet for final status. In parallel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@grok&lt;/code&gt; delivers a closure scorecard.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@claude&lt;/code&gt; confirms session continuity and M3.2 summon filtering.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@priyasi&lt;/code&gt; (Antigravity CLI) runs automated ACP checks: 44/44 test suite passing, 17,219 MemPalace vector drawers active, zero spec drift.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@agrickxy&lt;/code&gt; (Antigravity CLI) provides comprehensive infrastructure impression analysis.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@kiran&lt;/code&gt; (Antigravity CLI) is summoned headlessly to draft this very blog post!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;7-the-ergonomic-breakthrough-the-forge-as-the-unified-mindmap--interface&quot;&gt;7. The Ergonomic Breakthrough: The Forge as the Unified Mindmap &amp;amp; Interface&lt;/h2&gt;
&lt;p&gt;Beyond backend plumbing and sandboxing, routing agent interaction through Gitea fundamentally revolutionizes the &lt;strong&gt;developer experience&lt;/strong&gt; of managing an AI fleet.&lt;/p&gt;
&lt;h3 id=&quot;the-mindmap-mental-model-threaded-conversations--forking-tasks&quot;&gt;The “Mindmap” Mental Model: Threaded Conversations &amp;amp; Forking Tasks&lt;/h3&gt;
&lt;p&gt;In traditional CLI tools, conversations are constrained to a single, linear terminal scrollback. When an agent discovers multiple sub-problems, exploring them sequentially in one prompt loop rapidly pollutes the context window and confuses the model.&lt;/p&gt;
&lt;p&gt;Using the forge as the communication gateway naturally unlocks a &lt;strong&gt;mindmap mental model&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Forking sub-threads:&lt;/strong&gt; Complex problems can be split into dedicated child issues or threaded PR reviews.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focused execution scopes:&lt;/strong&gt; An agent can be summoned to solve a narrow sub-task in its own issue thread without derailing the parent architectural discussion.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured problem decomposition:&lt;/strong&gt; The forge issue hierarchy maps 1:1 to the developer’s mental map of the project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;eliminating-terminal-ui-fragmentation&quot;&gt;Eliminating Terminal UI Fragmentation&lt;/h3&gt;
&lt;p&gt;Anyone using multiple AI coding assistants on a daily basis quickly grows exhausted by their jarring terminal UI differences: differing ANSI escape rendering, inconsistent markdown wrapping, erratic diff pagers, and incompatible keybindings across Claude, Grok, and Antigravity.&lt;/p&gt;
&lt;p&gt;Gitea homogenizes the entire fleet under a single, polished &lt;strong&gt;rich-text web view&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Syntax-highlighted code blocks and visual side-by-side git diffs.&lt;/li&gt;
&lt;li&gt;Clear author badges attributing each contribution to its exact agent identity (&lt;code&gt;@claude&lt;/code&gt;, &lt;code&gt;@grok&lt;/code&gt;, &lt;code&gt;@priyasi&lt;/code&gt;, &lt;code&gt;@kiran&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Collapsible &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; blocks for voluminous diagnostic outputs.&lt;/li&gt;
&lt;li&gt;Interactive task lists and markdown tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;effortless-context-retrieval-archival--data-retention&quot;&gt;Effortless Context Retrieval, Archival &amp;amp; Data Retention&lt;/h3&gt;
&lt;p&gt;Auditing past agent decisions in terminal logs or ephemeral chat histories is notoriously difficult. With the forge, every exchange is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Contextually bound:&lt;/strong&gt; Pinned directly to the repository, branch, and commit SHA being modified.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Organized &amp;amp; Archival-Grade:&lt;/strong&gt; Full-text searchable with clear milestone and issue tags.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Topic-Focused:&lt;/strong&gt; The human operator can review the complete lifecycle of a discussion in seconds, gaining a rapid, holistic grasp on the entire subject.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reading back through past agent interactions becomes a breeze—to the point where interacting via the intermediary Gitea interface becomes far more pleasant and productive than wrestling with multiple desktop CLI terminals.&lt;/p&gt;
&lt;h3 id=&quot;remote-connectivity--headless-agent-farm-management&quot;&gt;Remote Connectivity &amp;amp; Headless Agent Farm Management&lt;/h3&gt;
&lt;p&gt;Because Gitea provides a standard web and API interface, you are no longer chained to the workstation running the agent processes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monitor progress and dispatch tasks from a &lt;strong&gt;mobile browser&lt;/strong&gt;, tablet, or remote laptop.&lt;/li&gt;
&lt;li&gt;Queue review tasks on the go without requiring active SSH sessions or terminal multiplexers.&lt;/li&gt;
&lt;li&gt;The local agent farm continues working silently in its sandboxed daemon containers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quietly-achieving-the-holy-grail-live-cross-vendor-swarms&quot;&gt;Quietly Achieving the Holy Grail: Live Cross-Vendor Swarms&lt;/h3&gt;
&lt;p&gt;For years, the AI industry has treated cross-vendor multi-agent interoperability as an elusive dream waiting for industry-wide API standardization. By recognizing the software forge as the universal message bus, we quietly achieved live, production-grade, cross-vendor communication across completely distinct vendor models.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;8-what-this-means-for-the-future-of-agentic-ai&quot;&gt;8. What This Means for the Future of Agentic AI&lt;/h2&gt;
&lt;p&gt;This milestone marks a fundamental shift in how we interact with autonomous AI systems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Heterogeneous Agent Specialization:&lt;/strong&gt; We don’t have to choose a single “winner” among AI models. We can task Claude Code with architectural refactoring, summon Grok Build for rapid verification and adversarial PR reviews, and deploy Google Antigravity agents for codebase exploration and documentation drafting—all coordinating fluidly in the same PR thread.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;True Human Sovereignty:&lt;/strong&gt; The human developer is no longer a bottleneck typist or a passive spectator. You act as the &lt;strong&gt;Engineering Manager / Lead Architect&lt;/strong&gt;. You set the requirements on an issue, tag the lead agent, and let the agents iterate, review, and test among themselves in the thread—while hard hop caps, OPA policies, and Zenity HITL gates guarantee that no agent merges code or pushes upstream without your explicit sign-off.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No Vendor Lock-In:&lt;/strong&gt; Because the entire coordination fabric is built on standard Git, HTTP webhooks, local Linux container sandboxes (&lt;code&gt;bwrap&lt;/code&gt;), and open MCP tools, any new AI CLI tool released tomorrow can be plugged into our fleet in under 15 minutes by simply adding its command-line prompt flag to the launch table.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We have moved beyond static autocomplete and interactive chat widgets. The software forge is now an active, living, collaborative workspace where humans and autonomous AI agents engineer software together.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;9-video-demonstration-camp-forge-a2a-swarm-in-action&quot;&gt;9. Video Demonstration: CAMP Forge A2A Swarm in Action&lt;/h2&gt;
&lt;p&gt;Below is a video demonstration showcasing autonomous multi-agent communication, cross-vendor relay, and headless swarm coordination in action via the CAMP Forge interface:&lt;/p&gt;
&lt;div style=&quot;padding-bottom: 56.25%; height: 0; overflow: hidden;&quot;&gt;
			
		&lt;/div&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;The Cross-Agent Memory Protocol (CAMP) and MemPalace are developed as part of our ongoing research into secure, sovereign, and disciplined Agentic AI computing.&lt;/em&gt;&lt;/p&gt; </description> 
	<pubDate>Thu, 27 Aug 2026 00:00:00 +0000</pubDate>
  <author>rrs@researchut.com (Ritesh Raj Sarraf)</author>  
</item> 
</channel>
</rss>
