<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On May 22, 2014, at 3:51 PM, Chandler Carruth <<a href="mailto:chandlerc@google.com">chandlerc@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 22, 2014 at 4:42 PM, Louis Gerbarg <span dir="ltr"><<a href="mailto:lgg@apple.com" target="_blank">lgg@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div id=":50a" class="a3s" style="overflow:hidden">The problem that the above transform is technically illegal because “When indexing into a (optionally packed) structure, only i32 integer constants are allowed (when using a vector of indices they must all be the same i32 integer constant).” rule <<a href="http://llvm.org/docs/LangRef.html#getelementptr-instruction" target="_blank">http://llvm.org/docs/LangRef.html#getelementptr-instruction</a>>.</div>
</blockquote></div><br>Wait, I don't follow. You don't violate this rule. The first index in GEP is *not* into the structure, it is along the implicit array of objects that any pointer refers to. Thus the i64 operand to the first GEP selects a different struct object in an array of them, and the first i64 operand to the second GEP re-selects the same struct object but then uses an i32 index into it. </div>
<div class="gmail_extra"><br></div><div class="gmail_extra">Perhaps you need a better example to show the illegal transform? That would help me understand the rest of your problem.</div></div>
</blockquote></div><div><br></div><div>Hmm… you are correct, it turns out you are correct, I only have to worry if it is constant after the second arg of the GEP. That should allow my case to continue to work. I am currently building a stage2 now to see if works cleanly.</div><div><br></div><div>Having said that, there still exist cases where you are indexing into a homogenous struct like so. Consider the following two functions, which are the same except one is written using structs and the other is written using arrays:</div><div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>%struct1 = type { i32, i32 }                                                    </div><div>%struct2 = type { %struct1, %struct1 }                                          </div><div>; Function Attrs: ssp uwtable                                                   </div><div>define i32 @test1(%struct2* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) {             </div><div>bb:                                                                             </div><div>  br i1 %tmp4, label %bb1, label %bb2                                           </div><div>bb1:                                              ; preds = %bb5                </div><div>  %tmp10 = getelementptr inbounds %struct2* %dm, i64 %tmp9, i32 0               </div><div>  br label %bb3                                                                 </div><div>                                                                                </div><div>bb2:                                             ; preds = %.lr.ph.i.i          </div><div>  %tmp20 = getelementptr inbounds %struct2* %dm, i64 %tmp9, i32 1              </div><div>  br label %bb3                                                                 </div><div>                                                                                </div><div>bb3:                                      ; preds = %bb2, %bb1                  </div><div>  %phi = phi %struct1* [ %tmp10, %bb1 ], [ %tmp20, %bb2 ]                       </div><div>  %tmp24 = getelementptr inbounds %struct1* %phi, i64 0, i32 1                  </div><div>  %tmp25 = load i32* %tmp24, align 4                                            </div><div>  ret i32 %tmp25                                                                </div><div>}                                                                               </div><div>                                                                                </div><div>                                                                                </div><div>%array1 = type [2 x i32]                                                        </div><div>%array2 = type [2 x %array1]                                                    </div><div>                                                                                </div><div>; Function Attrs: ssp uwtable                                                   </div><div>define i32 @test2(%array2* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) {              </div><div>bb:                                                                             </div><div>  br i1 %tmp4, label %bb1, label %bb2                                           </div><div>bb1:                                              ; preds = %bb5                </div><div>  %tmp10 = getelementptr inbounds %array2* %dm, i64 %tmp9, i32 0                </div><div>  br label %bb3                                                                 </div><div>                                                                                </div><div>bb2:                                             ; preds = %.lr.ph.i.i          </div><div>  %tmp20 = getelementptr inbounds %array2* %dm, i64 %tmp19, i32 1               </div><div>  br label %bb3                                                                 </div><div>                                                                                </div><div>bb3:                                      ; preds = %bb2, %bb1                  </div><div>  %phi = phi %array1* [ %tmp10, %bb1 ], [ %tmp20, %bb2 ]                        </div><div>  %tmp24 = getelementptr inbounds %array1* %phi, i64 0, i32 1                   </div><div>  %tmp25 = load i32* %tmp24, align 4                                            </div><div>  ret i32 %tmp25                                                                </div><div>}</div></blockquote><div><br></div><div>The @test1 function cannot have the optimization applied because the %tmp10 and %tmp20 GEPs vary by a field index into the struct, whereas @test2 can be optimized to:</div><div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>define i32 @test2([2 x [2 x i32]]* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) {</div><div>bb:</div><div>  br i1 %tmp4, label %bb1, label %bb2</div><div><br></div><div>bb1:                                              ; preds = %bb</div><div>  br label %bb3</div><div><br></div><div>bb2:                                              ; preds = %bb</div><div>  br label %bb3</div><div><br></div><div>bb3:                                              ; preds = %bb2, %bb1</div><div>  %0 = phi i32 [ 0, %bb1 ], [ 1, %bb2 ]</div><div>  %tmp24 = getelementptr inbounds [2 x [2 x i32]]* %dm, i64 %tmp9, i32 %0, i32 1</div><div>  %tmp25 = load i32* %tmp24, align 4</div><div>  ret i32 %tmp25</div><div>}</div></blockquote><div><br></div><div>Louis</div><div><br></div><div><br></div></body></html>