Hi All, I came across a FileCheck failure I don't understand why. The example code below: void test1() { ... code ... // CHECK-LABEL: @test1 // CHECK: void @llvm.memcpy.p0i8.p0i8.i32 - (1) } void dummy() { // make (1) match ... code ... // CHECK-LABEL: @dummy } void test2() { ... code ... // CHECK-LABEL: @test2 // CHECK: void @llvm.memcpy.p0i8.p0i8.i32 } Here what I want to match are the two llvm.memcpy instructions in function test1 and test2. If I don't place a dummy function between function test1 and test2, the first llvm.memcpy won't match even it indeed emitted (FileCheck says it cannot find the first llvm.memcpy). However, if I change to use CHECK instead of CHECK-LABEL, I don't need the dummy function anymore, and both llvm.memcpy get matched. So my questions are: 1. when I use CHECK-LABEL, why the first llvm.memcpy cannot be matched unless I add a dummy function? 2. why the problem gone if I change to use CHECK? 3. after reading the document [1], I am still not sure when CHECK-LABEL should/must be used. could you exactly point it out? Thanks. [1] http://llvm.org/docs/CommandGuide/FileCheck.html Regards, chenwj -- Wei-Ren Chen (陳韋任) Homepage: http://people.cs.nctu.edu.tw/~chenwj
Hi, CHECK-LABEL splits up the output into chunks before applying the rest of the CHECKs. This has a couple of benefits for testing: 1. Used carefully you can make sure FileCheck is looking at the right part of the output for the rest of your test (e.g. not in a completely different function). 2. If there are multiple errors FileCheck will tell you about one of them per block rather than just stopping at the first error in the file. On 31 March 2017 at 05:29, 陳韋任 via llvm-dev <llvm-dev at lists.llvm.org> wrote:> 1. when I use CHECK-LABEL, why the first llvm.memcpy cannot be > matched unless I add a dummy function?We'd need to see the real .ll file to be sure. Typically this happens because the CHECK-LABEL is picking up an earlier reference to its string than the one you intend. For example if @test1 called @test2 before doing its memcpy, the first block would end at that call rather than at the definition of @test2. You can probably fix this by including more context in the CHECK-LABEL lines. Maybe something like "CHECK-LABEL: define void @test1".> 2. why the problem gone if I change to use CHECK?In that case the whole file is checked at once. The "CHECK: @test2" line won't be picking up what you think it is, but there's still a memcpy afterwards so it works. Cheers. Tim.
Hi Tim, You're right, "CHECK-LABEL: define void @test1" solves the problem. Turns out the *.ll looks kinda of like: @test1 = whatsoever ... @test2 = whatsoever ... define void @test1() { ... code ... call void @llvm.memcpy.p0i8.p0i8.i32 } define void @test2() { ... code ... callvoid @llvm.memcpy.p0i8.p0i8.i32 } "CHECK-LABEL: @test1" and "CHECK-LABEL: @test2" divide above code into the following blocks: ---------------------------------------------------- |@test1 = whatsoever ... | ----------------------------------------------------- ---------------------------------------------------- |@test2 = whatsoever ... | | | |define void @test1() { | | ... code ... | | | | call void @llvm.memcpy.p0i8.p0i8.i32 | |} | | | |define void @test2() { | | ... code ... | | | | callvoid @llvm.memcpy.p0i8.p0i8.i32 | |} | ---------------------------------------------------- Apparently, we can't match llvm.memcpy in the first block. Adding function dummy with "CHECK-LABEL: @dummy" between function test1 and test2 just happen to divide the *.ll into three blocks. Fist and third block contain llvm.memcpy correspondingly. ---------------------------------------------------- |@test1 = whatsoever ... | |@test2 = whatsoever ... | | | |define void @test1() { | | ... code ... | | | | call void @llvm.memcpy.p0i8.p0i8.i32 | |} | ---------------------------------------------------- ---------------------------------------------------- |define void @dummy() { | | ... code ... | |} | ---------------------------------------------------- ---------------------------------------------------- | |define void @test2() { | | ... code ... | | | | callvoid @llvm.memcpy.p0i8.p0i8.i32 | |} | ---------------------------------------------------- The right solution is "CHECK-LABEL: define void @test1" and "CHECK-LABEL: define void @test2", which divide the *.ll into two blocks and match llvm.memcpy as we expect. ---------------------------------------------------- |define void @test1() { | | ... code ... | | | | call void @llvm.memcpy.p0i8.p0i8.i32 | |} | ---------------------------------------------------- ---------------------------------------------------- | | |define void @test2() { | | ... code ... | | | | callvoid @llvm.memcpy.p0i8.p0i8.i32 | |} | ---------------------------------------------------- Thanks, Tim. Hope this thread can help others. :p Regards, chenwj -- Wei-Ren Chen (陳韋任) Homepage: https://people.cs.nctu.edu.tw/~chenwj