google / xls

XLS: Accelerated HW Synthesis
http://google.github.io/xls/
Apache License 2.0
1.17k stars 171 forks source link

JIT/interpreter miscompare, crasher dba9 #366

Open meheff opened 3 years ago

meheff commented 3 years ago

This has a simple reduced test case:

package sample

fn __sample__main(x0: bits[61]) -> bits[122] {
  x1: bits[61] = add(x0, x0, id=2, pos=0,3,21)
  reverse.19: bits[61] = reverse(x1, id=19, pos=0,14,24)
  ret x12: bits[122] = concat(reverse.19, reverse.19, id=21, pos=0,14,24)
}

Running eval main:

With the JIT:

/xls/tools/eval_ir_main  --input="bits[61]:0x1" bad.ir --use_llvm_jit=true
bits[122]:0x800_0000_0000_0000

With the interpreter:

/xls/tools/eval_ir_main  --input="bits[61]:0x1" bad.ir --use_llvm_jit=false
bits[122]:0x100_0000_0000_0000_0800_0000_0000_0000

With the JIT without optimizations

/xls/tools/eval_ir_main  --input="bits[61]:0x1" bad.ir --use_llvm_jit=true --llvm_opt_level=0
bits[122]:0x100_0000_0000_0000_0800_0000_0000_0000

Unfortunately does not repro outside of the JIT (with lli, or llc followed by gcc to generate an executable). For the record a self contained ll file:

declare i61 @llvm.bitreverse.i61(i61) #0

define i122 @opt_f(i61 %x0) {
  %x1 = shl i61 %x0, 1
  %reverse_19 = tail call i61 @llvm.bitreverse.i61(i61 %x1)
  %_6 = zext i61 %reverse_19 to i122
  %x12 = mul nuw nsw i122 %_6, 2305843009213693953
  ret i122 %x12
}

define i122 @f(i61 %x0) {
  %x1 = add i61 %x0, %x0
  %reverse_19 = call i61 @llvm.bitreverse.i61(i61 %x1)
  %_7 = zext i61 %reverse_19 to i122
  %_8 = shl i122 %_7, 61
  %_9 = or i122 0, %_8
  %_10 = zext i61 %reverse_19 to i122
  %_11 = shl i122 %_10, 0
  %_12 = or i122 %_9, %_11
  ret i122 %_12
}

define i32 @main() {
entry:
  %_0 = call i122 @opt_f(i61 1)
  %_1 = lshr i122 %_0, 120
  %_2 = trunc i122 %_1  to i32
  ret i32 %_2
}
meheff commented 3 years ago

Also seems to require wide types and an odd number of bits for the function parameter.

meheff commented 3 years ago

Looks like the LLVM IR-level optimizations are ok: https://alive2.llvm.org/ce/z/8UB2Rg. See alive output below.

This suggests this might be a codegen bug in LLVM.

Alive output:

define i122 @f(i61 %x0) { %0: %x1 = add i61 %x0, %x0 %reverse_19 = bitreverse i61 %x1 %_7 = zext i61 %reverse_19 to i122 %_8 = shl i122 %_7, 61 %_9 = or i122 0, %_8 %_10 = zext i61 %reverse_19 to i122 %_11 = shl i122 %_10, 0 %x12 = or i122 %_9, %_11 ret i122 %x12 } => define i122 @f(i61 %x0) { %0: %x1 = shl i61 %x0, 1 %reverse_19 = bitreverse i61 %x1 %_7 = zext i61 %reverse_19 to i122 %x12 = mul nsw nuw i122 %_7, 2305843009213693953 ret i122 %x12 } Transformation seems to be correct!

Summary: 1 correct transformations 0 incorrect transformations 0 Alive2 errors