<div dir="ltr"><font face="monospace">This is a test case from `Transforms/GVN/PRE/pre-after-rle.ll`.<br><br>Before GVN, the MemorySSA beginning looks like:<br><br>    define void @fn1(i32** noalias %start, i32* %width, i32 %h) {<br>    entry:<br>    ; 1 = MemoryDef(liveOnEntry)<br>      %call = tail call noalias i8* @malloc(i64 1024)<br>      %call.cast = bitcast i8* %call to i32*<br>    ; 2 = MemoryDef(1)<br>      store i32* %call.cast, i32** %start, align 8<br>      br label %preheader<br>     <br>    preheader:                                        ; preds = %body, %entry<br>    ; 5 = MemoryPhi({entry,2},{body,3})<br>      %cmp = icmp slt i32 1, %h<br>      br i1 %cmp, label %body, label %exit<br>     <br>    body:                                             ; preds = %body, %preheader<br>    ; 4 = MemoryPhi({preheader,5},{body,3})<br>      %j = phi i32 [ 0, %preheader ], [ %j.next, %body ]<br>    ; MemoryUse(2) MayAlias<br>      %s = load i32*, i32** %start, align 8<br>      %idx = getelementptr inbounds i32, i32* %s, i64 0<br>    ; 3 = MemoryDef(4)<br>      store i32 0, i32* %idx, align 4<br>      %j.next = add nuw nsw i32 %j, 1<br>    ; MemoryUse(3) MayAlias<br>      %w = load i32, i32* %width, align 8<br>      %cmp3 = icmp slt i32 %j.next, %w<br>      br i1 %cmp3, label %body, label %preheader<br>     <br>    exit:                                             ; preds = %preheader<br>      ret void<br>    }<br><br><br>Note that `%w = load ...` is a `MemoryUse` of `store i32 0, i32* %idx`.<br><br>After GVN has removed the fully redundant load `%s = ...`, the<br>MemorySSA looks like:<br><br>    define void @fn1(i32** noalias %start, i32* %width, i32 %h) {<br>    entry:<br>    ; 1 = MemoryDef(liveOnEntry)<br>      %call = tail call noalias i8* @malloc(i64 1024)<br>      %call.cast = bitcast i8* %call to i32*<br>    ; 2 = MemoryDef(1)<br>      store i32* %call.cast, i32** %start, align 8<br>      br label %preheader<br>     <br>    preheader:                                        ; preds = %body, %entry<br>    ; 5 = MemoryPhi({entry,2},{body,3})<br>      %cmp = icmp slt i32 1, %h<br>      br i1 %cmp, label %body, label %exit<br>     <br>    body:                                             ; preds = %body, %preheader<br>    ; 4 = MemoryPhi({preheader,5},{body,3})<br>      %j = phi i32 [ 0, %preheader ], [ %j.next, %body ]<br>    ; 3 = MemoryDef(4)<br>      store i32 0, i32* %call.cast, align 4<br>      %j.next = add nuw nsw i32 %j, 1<br>    ; MemoryUse(3) MayAlias<br>      %w = load i32, i32* %width, align 8<br>      %cmp3 = icmp slt i32 %j.next, %w<br>      br i1 %cmp3, label %body, label %preheader<br>     <br>    exit:                                             ; preds = %preheader<br>      ret void<br>    }<br><br>The `%w = load ...` is still a use of the `store i32 0, i32*...`.<br><br>However, the locations now can be determined to not alias, and the<br>MemorySSA walker in fact skips `3 = MemoryDef(4)` and returns<br>`liveOnEntry` when queried for the clobber of `%w = load ...`.<br><br>So far so good, but then the `%w = load ... ` is not among the uses of<br>`liveOnEntry`.<br><br>This seems to contradict this part from the MemorySSA docs:<br><br>    "Unlike other partitioned forms, LLVM’s MemorySSA does make one<br>    useful guarantee - all loads are optimized to point at the thing<br>    that actually clobbers them. This gives some nice properties. For<br>    example, for a given store, you can find all loads actually<br>    clobbered by that store by walking the immediate uses of the<br>    store."<br><br>Is this the intended behaviour? Should MemorySSAUpdate<span class="gmail_default" style="font-family:monospace,monospace;font-size:small">r</span> have an update<br>API for when the address operands of loads/stores change?<br><br>~chill<br><br>-- <br>Compiler scrub, Arm</font></div>