Coder Social home page Coder Social logo

Comments (4)

HertzDevil avatar HertzDevil commented on July 4, 2024 1

Yet another issue is that T may have a larger alignment than the object. Since Pointer(T)#value assumes the pointer to have T's alignment, code like below can in general lead to bad codegen:

# `x` has byte alignment
x = uninitialized UInt8[16]
# `y` assumes `pointerof(x).address.divisible_by?(alignof(UInt128))`
y = pointerof(x).as(UInt128*).value
  %x = alloca [16 x i8], align 1
  %y = alloca i128, align 16
; ...
  %0 = load i128, ptr %x, align 16
  store i128 %0, ptr %y, align 16

If #unsafe_as codegens to a fresh call stack, then everything will happen to work because stack frames are 16-byte-aligned for most targets, but this is not guaranteed for release builds. Instead one must write %0 = load i128, ptr %x, align 1, and at the moment there is no language capability that could achieve this.

from crystal.

HertzDevil avatar HertzDevil commented on July 4, 2024 1

If LLVM cannot infer any stricter alignment it will generate individual byte reads for the load i128.

from crystal.

HertzDevil avatar HertzDevil commented on July 4, 2024

There is a second issue here. #unsafe_as can trigger dynamic dispatch: (contrast with #12846)

x = 123 || nil
alias T = UInt8[4]
x.unsafe_as(T)            # => StaticArray[123, 0, 0, 0]
pointerof(x).as(T*).value # => StaticArray[183, 0, 0, 0]
x.crystal_type_id         # => 183

It seems we actually want the second behavior, which can be done by simply rewriting Object#unsafe_as as a class method:

class Object
  def self.unsafe_cast(obj) : self
    pointerof(obj).as(self*).value
  end
end

T.unsafe_cast(x) # => StaticArray[183, 0, 0, 0]

Still, this formally involves copying obj, which is undesirable for large structs. So maybe pseudo-method is the way to go?

On the other hand, if we are keeping the dynamic dispatch then I don't know what benefits a pseudo-method or primitive would bring.

from crystal.

ysbaddaden avatar ysbaddaden commented on July 4, 2024

@HertzDevil but then we'd read the i128 unaligned, right? would it work on ARM?

Could the compiler detect this and directly align x as if it was an UInt128? maybe through a C union? Hum, I'm probably being very naive, here 😅

from crystal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.