There is currently no test in the repo to check the correctness of BrainF example. The aim of this PR is to just add a simple test case for it.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
llvm/test/Examples/BrainF/HelloWorld.ll | ||
---|---|---|
11 | %tape2 = add i8 %tape, 8 |
The two programs are identical, right? If so, you can put more than one RUN line in a single file to test it. Then use FileCheck --check-prefix=EXEC %s, EXEC: Hello World!.
llvm/test/Examples/BrainF/HelloWorld.ll | ||
---|---|---|
11 | Why does it need to be a regex when none of the other lines are? Either way, a single-use regex in FileCheck is surrounded by double curly-braces: {{.*}}. If you want to capture it to check against later code, you use double brackets. You often see something like: [[TAPE:%.*]] = load i8 [[TAPE2:%.*]] = add i8 [[TAPE]], 8 which would remember what the load got called and make sure the next line used the same SSA variable. |
Hello @t.p.northover and @jrtc27!
Thanks for giving time for reviewing the revision. I understand most things but when I combine two test cases in one file using --check-prefix=, check seems to start failing, So instead of updating the patch I copy-paste the test case here.
; RUN: BrainF %s -o - | llvm-dis | FileCheck --check-prefix=CHECK %s ; RUN: BrainF %s -o - | lli 2>&1 | FileCheck --check-prefix=EXEC %s ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. # CHECK-LABEL: define void @brainf() { # CHECK-NEXT: brainf: # CHECK-NEXT: %malloccall = tail call i8* @malloc(i32 mul (i32 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i32), i32 65536)) # CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* %malloccall, i8 0, i32 65536, i1 false) # CHECK-NEXT: %head = getelementptr i8, i8* %malloccall, i32 32768 # CHECK-NEXT: %tape = load i8, i8* %head, align 1 # CHECK: store i8 %tape2, i8* %head, align 1 # CHECK: br label %brainf3 # CHECK: brainf1: ; preds = %brainf55 # CHECK-NEXT: tail call void @free(i8* %malloccall) # CHECK-NEXT: ret void # CHECK: } # CHECK-LABEL: define i32 @main(i32 %argc, i8** %argv) { # CHECK-NEXT: main.0: # CHECK-NEXT: call void @brainf() # CHECK-NEXT: ret i32 0 # CHECK: } # EXEC: Hello World!
Please tell me what I am missing now?
(Sorry for the late reply, my laptop went for repairing)
Please tell me what I am missing now?
I think the issue is that the symbols in the RUN line (- and >) are being executed as BF code. Looking at Wikipedia, surrounding the RUN lines with a loop [] makes them a nop (since the tape starts at 0). That recovers the "Hello World!" but does still perturb -O0 codegen of course. Which is probably OK.
I think the issue is that the symbols in the RUN line (- and >) are being executed as BF code.
I doubt it. because when I run test files separately they are passing. The issue occurs when I merge them in a single file.
Looking at Wikipedia, surrounding the RUN lines with a loop [] makes them a nop (since the tape starts at 0). That recovers the "Hello World!" but does ?still perturb -O0 codegen of course. Which is probably OK.
Could you please suggest RUN line by example, I tried some configurations, It doesn't work on my system.
llvm/test/Examples/BrainF/HelloWorld.ll | ||
---|---|---|
2 | I think it may not be needed. I have seen some other testcases. Is this testcase doing something different to require default_triple? |
@awarzynski Would you please take a look at these two testcases whenever get the time? Test starts failing when I combine them into a single testcase using check-prefix. I really wish to commit my first testcase.
I doubt it. because when I run test files separately they are passing. The issue occurs when I merge them in a single file.
That adds more perturbations to the initial tape state which is enough to break the "Hello World" output.
Could you please suggest RUN line by example, I tried some configurations, It doesn't work on my system.
This worked for me:
[ ; RUN: BrainF %s -o - | llvm-dis | FileCheck --check-prefix=CHECK %s ; RUN: BrainF %s -o - | lli 2>&1 | FileCheck --check-prefix=EXEC %s ]
Though it seems there's extra output from the CHECK lines too. It might actually be better to put the BF code in its own completely separate file (this is usually put in an Inputs subdirectory and referred to as %p/Inputs/helloworld.bf instead of the test name %s).
I believe that this is what we want here:
[ RUN: BrainF %s -o - | llvm-dis | FileCheck --check-prefix=CHECK %s RUN: BrainF %s -o - | lli 2>&1 | FileCheck --check-prefix=EXEC %s CHECK-LABEL: define void @brainf() { CHECK-NEXT: brainf: CHECK-NEXT: %malloccall = tail call i8* @malloc(i32 mul (i32 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i32), i32 65536)) CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* %malloccall, i8 0, i32 65536, i1 false) CHECK-NEXT: %head = getelementptr i8, i8* %malloccall, i32 32768 CHECK-NEXT: %tape = load i8, i8* %head, align 1 CHECK: store i8 %tape2, i8* %head, align 1 CHECK: br label %brainf3 CHECK: brainf1: ; preds = %brainf55 CHECK-NEXT: tail call void @free(i8* %malloccall) CHECK-NEXT: ret void CHECK: } CHECK-LABEL: define i32 @main(i32 %argc, i8** %argv) { CHECK-NEXT: main.0: CHECK-NEXT: call void @brainf() CHECK-NEXT: ret i32 0 CHECK: } EXEC: Hello World! ] ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Basically, the first loop is completely ignored and can be used for input for LIT/FileCheck. This solution is inspired by the HelloWorld eample from Wikipedia. Note that there is no need to use ; or #, that's ignored by BrainF anyway.
Other points:
- I would rename the test file as e.g. HelloWorld.bf as this is not an LLVM IR file (so *.ll is a bit confusing)
- Could you add a comment that explains what that BF examples does?
- I'm using LLVM 11 and get slightly different IR (e.g. labels). It's probably worth using more regex here and focusing on the key bits a bit more.
EDIT
I've just realized that that comment between [ and ] does affect the generated IR. It doesn't affect the runtime behavior though. I think that moving the actual input to a dedicated file in llvm/test/Examples/BrainF/Inputs might be the cleanest approach. Also, have you consider testing something more basic? E.g. [-]? The IR for that is very easy to follow (and test).
Sorry reviewers Currently I am not very motivated to complete this patch.
@jnyfah or @sushmaunnibhavi, would you want to take this task and complete it for your Outreachy application.
Yes i would, i am currently checking it out, i will reach out if i have any
issues with it
Thanks alot Shivam
Probably ; REQUIRES: default_triple?