everx-labs / TVM-Compiler

Clang compiler for TVM
Apache License 2.0
60 stars 16 forks source link

Bitfields are not compiled correctly #281

Open NoamDev opened 2 years ago

NoamDev commented 2 years ago

While TVM-llvm only supports i257 type, in bit fields, it still chooses types like i128.

Reproduce Instructions:

Contract.cpp

struct my_bitfield{
  unsigned field: 128;
};
int main(){
  my_bitfield c;
  c.field =1;
}

compile command:

/path/to/toolchain/opt/work/llvm/install/bin/clang++ -target tvm -O0 -S -emit-llvm Contract.cpp \
-o ir-code.ll --sysroot=/path/to/toolchain/opt/work/llvm/install/bin/..

Note: The -O0 is important, -O3 would optimize the problem away in simple cases such as this example.

Resulting IR code:

; ModuleID = 'src/Contract.cpp'
source_filename = "src/Contract.cpp"
target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257"
target triple = "tvm"

%struct.my_bitfield = type { i128 }

; Function Attrs: noinline norecurse nounwind optnone
define dso_local i257 @main() #0 {
  %1 = alloca %struct.my_bitfield, align 1
  %2 = bitcast %struct.my_bitfield* %1 to i257*
  %3 = load i257, i257* %2, align 1
  %4 = and i257 %3, 680564733841876926926749214863536422911
  %5 = or i257 %4, 680564733841876926926749214863536422912
  store i257 %5, i257* %2, align 1
  ret i257 0
}

attributes #0 = { noinline norecurse nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 1}
!1 = !{!"TON Labs clang for TVM. Version 7.7.22  (based on LLVM 7.7.22)"}

Note the "i128" in line number 4.

azhogin commented 2 years ago

Also, we have problems with masks:

so I replaced the bitfields with masks). However I'm still getting errors.

LLVM ERROR: Cannot select: 0x2e1d320: i257 = ctlz 0x2e13308
  0x2e13308: i257,ch = CopyFromReg 0x2dd2198, Register:i257 %31
    0x2e12dc0: i257 = Register %31
LLVM ERROR: Cannot select: 0x353b5c8: i257 = sign_extend_inreg 0x353c398, ValueType:ch:i128
  0x353c398: i257,ch = CopyFromReg 0x34230b8, Register:i257 %9
    0x353bde8: i257 = Register %9