<div dir="ltr"><div><div><div><div>Consider the following:<br><br>t<span style="font-family:monospace,monospace">arget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"<br>target triple = "x86_64-unknown-linux-gnu"<br><br>%UodStructType = type { i8, i8, i8, i8, i32, i8* }<br><br>define void @test(%UodStructType*) {<br>    %2 = getelementptr inbounds %UodStructType* %0, i32 0, i32 0<br>    store i8 1, i8* %2, align 8<br>    %3 = getelementptr inbounds %UodStructType* %0, i32 0, i32 1<br>    store i8 2, i8* %3, align 1<br>    %4 = getelementptr inbounds %UodStructType* %0, i32 0, i32 2<br>    store i8 3, i8* %4, align 2<br>    %5 = getelementptr inbounds %UodStructType* %0, i32 0, i32 3<br>    store i8 4, i8* %5, align 1<br>    ret void<br>}<br></span><br></div>If I run this through opt -O3, it passes through unchanged.<br><br></div>However, I would think that it would be profitable to combine the stores into a single instruction, e.g.:<br><br><span style="font-family:monospace,monospace">define void @test(%UodStructType*) {<br></span></div><span style="font-family:monospace,monospace">    %2 = bitcast %UodStructType* %0 to i32*<br></span></div><span style="font-family:monospace,monospace">    store i32 0x04030201, i32* %2, align 8<br></span><div><div><span style="font-family:monospace,monospace">    ret void<br>}</span><br><br></div><div>I don't see any optimization that would do this.<br><br>Interestingly, if I store the same 8-bit constant in all four bytes, then MemCpyOpt will indeed convert this to a 32-bit store. <br><br></div><div>Am I doing something wrong, or is there really no optimization pass that can clean this up?<br><br></div></div></div>