chsasank / llama.lisp

Lisp dialect designed for HPC and AI
GNU Lesser General Public License v2.1
14 stars 6 forks source link

Error while casting from Int -> Int8 -> Int. #69

Closed adi-lb-phoenix closed 2 months ago

adi-lb-phoenix commented 2 months ago

The below brilisp code can be used for regression test. Brilisp code :

(brilisp 
    (define ((print int) (n int)))

    (define ((convert int) (n int))
        (set (f_n int8_t) (trunc n))
        (set (f_n int) (sext f_n))
        (ret f_n))

    (define (( main void)) 
        (set (a int) (const 255))
        (set (b int) (call convert a))
        (set (tmp int) (call print b))
        (ret)))

Whats the issue ? So when the below line of code is present

        (set (f_n int8_t) (trunc n))
        (set (f_n int) (sext f_n))

No operation of sign extension is done on f_n . That is f_n will be truncated to i8 that is 8 bit but will not be undergo a sign extension operation to i32 . It is to be noted that this kind of operation happens only when the variable is in lower bit order and needs to be converted to higher bit order.

LLVM IR : Command used : guile ../../../../utils/sexp-json.scm < int_to_i8_to_int.sexp | python ../../../../brilisp.py | python ../../../../llvm.py |

; ModuleID = ""
target triple = "unknown-unknown-unknown"
target datalayout = ""

declare i32 @"print"(i32 %".1")

define i32 @"convert"(i32 %"n")
{
alloca-xmpajuye:
  %"n.1" = alloca i32
  %"f_n" = alloca i8
  %"f_n.2" = alloca i32
  br label %"entry-ufylhykv"
entry-ufylhykv:
  store i32 %"n", i32* %"n.1"
  %".4" = load i32, i32* %"n.1"
  %"f_n.1" = trunc i32 %".4" to i8
  store i8 %"f_n.1", i8* %"f_n"
  %".6" = load i32, i32* %"f_n.2"
  store i32 %".6", i32* %"f_n.2"
  %".8" = load i32, i32* %"f_n.2"
  ret i32 %".8"
}

define void @"main"()
{
alloca-oogbsbgn:
  %"a" = alloca i32
  %"b" = alloca i32
  %"tmp" = alloca i32
  br label %"entry-ulhgybse"
entry-ulhgybse:
  store i32 255, i32* %"a"
  %".3" = load i32, i32* %"a"
  %"b.1" = call i32 @"convert"(i32 %".3")
  store i32 %"b.1", i32* %"b"
  %".5" = load i32, i32* %"b"
  %"tmp.1" = call i32 @"print"(i32 %".5")
  store i32 %"tmp.1", i32* %"tmp"
  ret void
}

But instead of using

        (set (f_n int8_t) (trunc n))
        (set (f_n int) (sext f_n))

use the below :

        (set (f_n int8_t) (trunc n))
        (set (a_n int) (sext f_n))

the code works properly. The llvm IR now contains the statements sext and. the output is as expected.

chsasank commented 2 months ago

Should be added as test to #68

chsasank commented 2 months ago

Fixed by #68