Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3.1k
Closed
Labels
Milestone
Description
constspi_tdr=packedstruct {unused1:u7,lastxfr:u1,unused2:u4,pcs:u4,td:u16,};exportfnentry(ptr:*volatilespi_tdr)void {vartmp=ptr.*;tmp.lastxfr=1;ptr.*=tmp;}
generates
definevoid@entry(%spi_tdr*nonnull) #2!dbg!80 {Entry:%ptr =alloca%spi_tdr*,align8%tmp =alloca%spi_tdr,align1store%spi_tdr*%0,%spi_tdr**%ptr,align8callvoid@llvm.dbg.declare(metadata%spi_tdr**%ptr,metadata!96,metadata!DIExpression()),!dbg!100%1 =load%spi_tdr*,%spi_tdr**%ptr,align8,!dbg!101%2 =bitcast%spi_tdr*%1toi8*,!dbg!102%3 =bitcast%spi_tdr*%tmptoi8*,!dbg!102callvoid@llvm.memcpy.p0i8.p0i8.i64(i8*align1%3,i8*align1%2,i644,i1false),!dbg!102callvoid@llvm.dbg.declare(metadata%spi_tdr*%tmp,metadata!97,metadata!DIExpression()),!dbg!102%4 =getelementptrinbounds%spi_tdr,%spi_tdr*%tmp,i320,i320,!dbg!103%5 =loadi8,i8*%4,align1,!dbg!105%6 =andi8%5,127,!dbg!105%7 =ori8 -128,%6,!dbg!105storei8%7,i8*%4,align1,!dbg!105%8 =load%spi_tdr*,%spi_tdr**%ptr,align8,!dbg!106%9 =bitcast%spi_tdr*%tmptoi8*,!dbg!107%10 =bitcast%spi_tdr*%8toi8*,!dbg!107callvoid@llvm.memcpy.p0i8.p0i8.i64(i8*align1%10,i8*align1%9,i644,i1true),!dbg!107retvoid,!dbg!108}
The problem here is call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %3, i8* align 1 %2, i64 4, i1 false), !dbg !102 and specifically the last argi1 false. That's a non-volatile load.
This load should be volatile.
Arguably Zig should generate a ptrcast from the struct pointer to a pointer to u32 since that is <= register size, but if LLVM is doing the same thing when lowering memcpys - which it appears to be doing - then it's fine just to set the volatile bit.
We don't really have a way to test this other than pattern-matching the resulting LLVM IR, so I think we'll have to add some tests that do that. I already need something like that for#1682.