From eccbd572eb434f3699bc7ba43e538f4431310691 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 9 Nov 2018 16:27:49 +0100 Subject: [PATCH] interp: do cast operations at runtime if needed Cast operations will still be evaluated at compile time in all cases they did before because of the built-in constant propagation of the IRBuilder, but when one of the parameters is not a constant it will transparently be evaluated at runtime. This avoids some errors in the partial evaluator. It is not yet complete as all binops will need a similar treatment. --- interp/frame.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/interp/frame.go b/interp/frame.go index 8c1e4c1e..e4827889 100644 --- a/interp/frame.go +++ b/interp/frame.go @@ -135,31 +135,31 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re // Cast operators case !inst.IsATruncInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstTrunc(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateTrunc(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsAZExtInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstZExt(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateZExt(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsASExtInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstSExt(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateSExt(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsAFPToUIInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstFPToUI(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateFPToUI(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsAFPToSIInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstFPToSI(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateFPToSI(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsAUIToFPInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstUIToFP(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateUIToFP(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsASIToFPInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstSIToFP(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateSIToFP(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsAFPTruncInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstFPTrunc(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateFPTrunc(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsAFPExtInst().IsNil(): value := fr.getLocal(inst.Operand(0)) - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstFPExt(value.(*LocalValue).Value(), inst.Type())} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateFPExt(value.(*LocalValue).Value(), inst.Type(), "")} case !inst.IsABitCastInst().IsNil() && inst.Type().TypeKind() == llvm.PointerTypeKind: operand := inst.Operand(0) if !operand.IsACallInst().IsNil() { @@ -179,12 +179,12 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re lhs := fr.getLocal(inst.Operand(0)).(*LocalValue).Underlying rhs := fr.getLocal(inst.Operand(1)).(*LocalValue).Underlying predicate := inst.IntPredicate() - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstICmp(predicate, lhs, rhs)} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateICmp(predicate, lhs, rhs, "")} case !inst.IsAFCmpInst().IsNil(): lhs := fr.getLocal(inst.Operand(0)).(*LocalValue).Underlying rhs := fr.getLocal(inst.Operand(1)).(*LocalValue).Underlying predicate := inst.FloatPredicate() - fr.locals[inst] = &LocalValue{fr.Eval, llvm.ConstFCmp(predicate, lhs, rhs)} + fr.locals[inst] = &LocalValue{fr.Eval, fr.builder.CreateFCmp(predicate, lhs, rhs, "")} case !inst.IsAPHINode().IsNil(): for i := 0; i < inst.IncomingCount(); i++ { if inst.IncomingBlock(i) == incoming {