<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Mar 30, 2009, at 1:34 PM, Misha Brukman wrote:</div><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div style=""><div class="im"><div><blockquote type="cite"><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Grepping through -debug output isn't very nice in any case, but at the<br>moment there aren't any better ways to express this specific test.<font color="#888888"><br> </font></blockquote></div><br>You can write a unittest to check this.  It might require some refactoring to be able to run all of LLC's passes separately from running the tool on the command line, since they are currently hard-coded in its main() function.<br> </span></blockquote></div></div><div>I don't think we want unit tests for passes.  We only want unit tests for low level APIs.</div></div></blockquote><div><br>Let's drop the term "unit" and just call them tests.</div></div></blockquote><div><br></div><div>Ok.</div><br><blockquote type="cite"><div class="gmail_quote"><div>I'm proposing we test passes in C++ instead of a shell script that calls grep.</div></div></blockquote><div><br></div><div>What is the real value of doing this?  The costs I see are 1) increased link time and 2) more dependence on the API (more to update when an API changes).</div><div><br></div><blockquote type="cite"><div class="gmail_quote"><div><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">How else can we check the correctness of a pass, which involves pattern-matching multiple instructions?  Grep can only look at a single line at a time, and doesn't have the semantic knowledge of what's an instruction and what's an operand, whereas we have all this information in C++.</span></div></div> </blockquote></div><br><div>I think the answer is that we need to build *one* small "llvmirgrep" tool that does this, which could be used by many different tests.</div><div><br></div><div>I don't know exactly the syntax for it, but I think it should be something like the tool we use in clang.  In clang, we write tests for diagnostics like this:</div><div><br></div><div><div>// RUN: clang-cc %s -verify -pedantic -fsyntax-only </div><div>void test4() {</div></div><div><div>      static int var;</div><div>      var =+ 5;  // expected-warning {{use of unary operator that may be intended as compound assignment (+=)}}</div><div>      var =- 5;  // expected-warning {{use of unary operator that may be intended as compound assignment (-=)}}</div><div>      var = +5;  // no warning when space between the = and +.</div><div>      var = -5;</div><div><br></div><div>      var =+5;  // no warning when the subexpr of the unary op has no space before it.</div><div>      var =-5;</div><div>  </div><div>#define FIVE 5</div><div>      var=-FIVE;  // no warning with macros.</div><div>      var=-FIVE;</div><div>}</div><div><br></div><div>In this case, the tool is built into clang, but it doesn't need to be.  The -verify mode basically runs the compiler as normal, but captures the generated diagnostics to a buffer.  It then scans the .c file for the "expected-" comments and "diffs" the generated and expected diagnostics.</div><div><br></div><div><br></div><div>If we had an llvmirgrep tool, then we could do something like this:</div><div><br></div><div><div>; RUN: llvm-as < %s | opt -instcombine | llvm-irgrep %s</div><div><br></div><div>define i32 @test(float %f) {</div><div>      ; irgrep {%t1 = bitcast float %f to i32}</div><div>      ; irgrep {ret i32 %t1}</div><div>        %tmp7 = insertelement <4 x float> undef, float %f, i32 0 </div><div>        %tmp17 = bitcast <4 x float> %tmp7 to <4 x i32>   </div><div>        %tmp19 = extractelement <4 x i32> %tmp17, i32 0</div><div>        ret i32 %tmp19</div><div>}</div><div><br></div><div>Which would be smart enough to require that those two instructions be in that basic block of that function, and it would do a fuzzy match to ignore the fact that the generated code names the first instruction "%tmp19".</div><div><br></div><div>This is based on test/Transforms/InstCombine/vec_extract_elt.ll, and is just a really hand wavy theoretical syntax just to get the idea across.</div></div><div><br></div><div>What do you think?</div><div><br></div><div>-Chris</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div></body></html>