Code generation problem

I was testing my implementation of the usual ternary function just
now, and it's giving the wrong answer; I would attribute this to an
error in my parser/abstract syntax tree code, but looking at the
output, as far as I can see, the intermediate code is correct at the
point where I hand it to LLVM's JIT. Could someone look and see if I'm
doing something wrong, misunderstanding the semantics of the
intermediate code format or something?

C:\aklo>ak
Aklo version 0 (32 bit)

1?2?3:4:5

declare void @abort()

define i32 @_main() {
  br i32 1, label %1, label %6

; <label>:1 ; preds = %0
  br i32 2, label %2, label %3

; <label>:2 ; preds = %1
  br label %4

; <label>:3 ; preds = %1
  br label %4

; <label>:4 ; preds = %3, %2
  %5 = phi i32 [ 3, %2 ], [ 4, %3 ] ; <i32> [#uses=1]
  br label %7

; <label>:6 ; preds = %0
  br label %7

; <label>:7 ; preds = %6, %4
  %8 = phi i32 [ %5, %4 ], [ 5, %6 ] ; <i32> [#uses=1]
  ret i32 %8
}
4

(result is 4, should be 3)

The condition on a branch instruction is not evaluated with C condition
semantics. It must be of i1 type, i.e. either true or false. Your IR should
(presumably) be more like:

  %c1 = icmp ne i32 1, i32 0
   br i1 %c1, label %yes, label %no
yes:
  %c2 = icmp ne i32 2, i32 0
  br i1 %c2, ....

Also, if you are producing IR yourself, you should always be running the IR
verification pass (at least in debug mode), which should catch structural
problems like this (and many others).

John.

Oh! Okay, thanks, I'll fix it up to do that then.

Any chance verifyFunction could be tightened up to catch this case?
I'm currently running all my generated code through it, and it passes
the i32 conditional without complaint.

Hi Russell,

  br i32 1, label %1, label %6

if you build LLVM with checking enabled, then you would not have been able to
create this bogus branch instruction: the BranchInst constructors assert if the
condition does not have type i1.

This does raise a philosophical question though: should the verifier try to
catch mistakes that constructors would catch if assertions are turned on?

Ciao,

Duncan.

Oh! Now I get it, that would be with the debug build of LLVM. Never
mind the request then, "use the debug build if you want full error
checking" is perfectly reasonable. I'll start doing that for the
moment.

This does raise a philosophical question though: should the verifier try to
catch mistakes that constructors would catch if assertions are turned on?

Yes please!

John

Duncan Sands wrote:

Hi Russell,

   br i32 1, label %1, label %6

if you build LLVM with checking enabled, then you would not have been able to
create this bogus branch instruction: the BranchInst constructors assert if the
condition does not have type i1.

This does raise a philosophical question though: should the verifier try to
catch mistakes that constructors would catch if assertions are turned on?

Yes, absolutely. In my ideal world you would be able to build a Release-Asserts LLVM and load a .bc file and run it through the verifier and have it catch any invalid or malformed bitcode.

Nick

Russell Wallace wrote:

Oh! Okay, thanks, I'll fix it up to do that then.

Any chance verifyFunction could be tightened up to catch this case?
I'm currently running all my generated code through it, and it passes
the i32 conditional without complaint.

Done in r96282. Thanks for the bug report!

Nick