<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 21, 2015, at 2:18 PM, Chandler Carruth <<a href="mailto:chandlerc@gmail.com" class="">chandlerc@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Jan 21, 2015 at 2:16 PM, Chandler Carruth<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:chandlerc@gmail.com" target="_blank" class="">chandlerc@gmail.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div dir="ltr" class="">So, we've run into some test cases which are pretty alarming.<div class=""><br class=""></div><div class="">When inlining code in various different paths we can end up with this IR:</div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">define void @f(float* %value, i8* %b) {<br class=""></font></div><div class=""><font face="monospace, monospace" class="">entry:</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>%0 = load float* %value, align 4</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>%1 = bitcast i8* %b to float*</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>store float %0, float* %1, align 1</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>ret void</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">define void @g(float* %value, i8* %b) {<br class=""></font></div><div class=""><font face="monospace, monospace" class="">entry:</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>%0 = bitcast float* %value to i32*</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>%1 = load i32* %0, align 4</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>%2 = bitcast i8* %b to i32*</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>store i32 %1, i32* %2, align 1</font></div><div class=""><font face="monospace, monospace" class=""> <span class="Apple-converted-space"> </span>ret void</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><br class=""></div></div><div class="">Now, I don't really care one way or the other about these two IR inputs, but it's pretty concerning that we get these two equivalent bits of code and nothing canonicalizes to one or the other.</div><div class=""><br class=""></div><div class="">So, the naive first blush approach here would be to canonicalize on the first -- it has fewer instructions after all -- but I don't think that's the right approach for two reasons:</div><div class=""><br class=""></div><div class="">1) It will be a *very* narrow canonicalization that only works with overly specific sets of casted pointers.</div><div class="">2) It doesn't effectively move us toward the optimizer treating IR with different pointee types for pointer types indistinguishably. Some day, I continue to think we should get rid of the pointee types entirely.</div><div class=""><br class=""></div><div class="">To see why #1 and #2 are problematic, assume another round of inlining took place and we suddenly had the following IR:</div><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">And the missing IR example:</div><div class=""><br class=""></div><div class=""><font face="monospace, monospace" class="">define void @f(i8* %value, i8* %b) {<br class=""></font></div><div class=""><font face="monospace, monospace" class="">entry:</font></div><div class=""><font face="monospace, monospace" class=""> %0 = bitcast i8* %value to float*</font></div><div class=""><font face="monospace, monospace" class=""> %1 = load float* %0, align 4</font></div><div class=""><font face="monospace, monospace" class=""> %2 = bitcast i8* %b to float*</font></div><div class=""><font face="monospace, monospace" class=""> store float %0, float* %1, align 1</font></div><div class=""><font face="monospace, monospace" class=""> ret void</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">define void @g(i8* %value, i8* %b) {<br class=""></font></div><div class=""><font face="monospace, monospace" class="">entry:</font></div><div class=""><font face="monospace, monospace" class=""> %0 = bitcast i8* %value to i32*</font></div><div class=""><font face="monospace, monospace" class=""> %1 = load i32* %0, align 4</font></div><div class=""><font face="monospace, monospace" class=""> %2 = bitcast i8* %b to i32*</font></div><div class=""><font face="monospace, monospace" class=""> store i32 %1, i32* %2, align 1</font></div><div class=""><font face="monospace, monospace" class=""> ret void</font></div><div class=""><span style="font-family: monospace, monospace;" class="">}</span></div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div dir="ltr" class=""><div class=""></div><div class=""><br class=""></div><div class="">AFAICT, this is the same and we still don't have a good canonicalization story.</div><div class=""><br class=""></div><div class="">What seems like the obvious important and missing canonicalization is that when we have a loaded value that is *only* used by storing it back into memory, we don't canonicalize the type of that *value* (ignoring the pointer types) to a single value type.</div><div class=""><br class=""></div><div class="">So, the only really suitable type for this kind of stuff is 'iN' where N matches the number of bits loaded or stored.</div><div class=""><br class=""></div><div class="">I have this change implemented. It is trivial and unsurprising. However, the effects of this are impossible to predict so I wanted to make sure it made sense to others. Essentially, I expect random and hard to track down performance fluctuations across the board. Some things may get better, others may get worse, and they will probably all be bugs elsewhere in the stack.</div><div class=""><br class=""></div><div class="">So, thoughts?</div></div></blockquote></div></div></div></div></blockquote>The first thing that springs to mind is that I don’t trust the backend to get this right. I don’t think it will understand when an i32 load/store would have been preferable to a float one or vice versa. I have no evidence of this, but given how strongly typed tablegen is, I don’t think it can make a good choice here.</div><div><br class=""></div><div>So I think we probably need to teach the backend how to undo whatever canonical form we choose if it has a reason to. And the best long term solution is for tablegen to have sized load/stores, not typed ones.</div><div><br class=""></div><div>One (potentially expensive) way to choose the canonical form here is to look at the users of the load and see what type works best. If we load an i32, but bit cast and do an fp operation on it, then a float load was best. If we just load it then store, then in theory either type works.</div><div><br class=""></div><div>Pete<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div dir="ltr" class=""><span class=""><font color="#888888" class=""><div class="">-Chandler</div></font></span></div></blockquote></div><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">LLVM Developers mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><a href="mailto:LLVMdev@cs.uiuc.edu" class="">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" class="">http://llvm.cs.uiuc.edu</a></span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a></span></div></blockquote></div><br class=""></body></html>