This is an archive of the discontinued LLVM Phabricator instance.

[Example][NFC} Add testcase for BrainF HelloWorld
AbandonedPublic

Authored by xgupta on Feb 2 2021, 9:38 PM.

Details

Summary

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.

Diff Detail

Event Timeline

xgupta requested review of this revision.Feb 2 2021, 9:38 PM
xgupta created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2021, 9:38 PM
xgupta added inline comments.Feb 2 2021, 9:40 PM
llvm/test/Examples/BrainF/HelloWorld.ll
11

%tape2 = add i8 %tape, 8
This line I also want to check here but don't how to write regex expression in FileCheck syntax. So after adding this check starts failing.

xgupta edited the summary of this revision. (Show Details)Feb 3 2021, 8:29 AM

gentle ping!

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.

jrtc27 added a subscriber: jrtc27.Feb 18 2021, 12:16 PM
jrtc27 added inline comments.
llvm/test/Examples/BrainF/HelloWorld.ll
2

Probably ; REQUIRES: default_triple?

5

These should generally be CHECK-LABEL

14

Don't put blank lines in the middle of functions

20

I doubt you care about these

28

Missing :

xgupta marked 4 inline comments as done.EditedFeb 19 2021, 8:43 AM

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.

xgupta updated this revision to Diff 325491.Feb 22 2021, 10:49 AM

Address few minor comments

xgupta added inline comments.Feb 22 2021, 10:52 AM
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.

xgupta edited reviewers, added: awarzynski; removed: fpichet, chapuni, resistor.Feb 23 2021, 11:35 PM

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).

awarzynski added a comment.EditedFeb 24 2021, 2:43 AM

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

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 Shivam I will work on this.

xgupta abandoned this revision.Apr 21 2021, 10:09 PM

Thanks to both of you and don't hesitate to ask if something is not clear.