interp: support some more expressions in const icmp
Этот коммит содержится в:
родитель
87ac804642
коммит
7156afca9e
2 изменённых файлов: 28 добавлений и 17 удалений
|
@ -188,23 +188,8 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
|
||||||
// Unfortunately, the const propagation in the IR builder
|
// Unfortunately, the const propagation in the IR builder
|
||||||
// doesn't handle pointer compares of inttoptr values. So we
|
// doesn't handle pointer compares of inttoptr values. So we
|
||||||
// implement it manually here.
|
// implement it manually here.
|
||||||
isNil := func(v llvm.Value) (result bool, ok bool) {
|
lhsNil, ok1 := isPointerNil(lhs)
|
||||||
if !v.IsAConstantExpr().IsNil() && v.Opcode() == llvm.IntToPtr {
|
rhsNil, ok2 := isPointerNil(rhs)
|
||||||
// Whether a constant inttoptr is nil is easy to
|
|
||||||
// determine.
|
|
||||||
operand := v.Operand(0)
|
|
||||||
if operand.IsConstant() {
|
|
||||||
return operand.ZExtValue() == 0, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !v.IsAConstantPointerNull().IsNil() {
|
|
||||||
// A constant pointer null is always null, of course.
|
|
||||||
return true, true
|
|
||||||
}
|
|
||||||
return false, false // not valid
|
|
||||||
}
|
|
||||||
lhsNil, ok1 := isNil(lhs)
|
|
||||||
rhsNil, ok2 := isNil(rhs)
|
|
||||||
if ok1 && ok2 {
|
if ok1 && ok2 {
|
||||||
if lhsNil && rhsNil {
|
if lhsNil && rhsNil {
|
||||||
// Both are nil, so this icmp is always evaluated to true.
|
// Both are nil, so this icmp is always evaluated to true.
|
||||||
|
|
|
@ -94,3 +94,29 @@ func isScalar(t llvm.Type) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isPointerNil returns whether this is a nil pointer or not. The ok value
|
||||||
|
// indicates whether the result is certain: if it is false the result boolean is
|
||||||
|
// not valid.
|
||||||
|
func isPointerNil(v llvm.Value) (result bool, ok bool) {
|
||||||
|
if !v.IsAConstantExpr().IsNil() {
|
||||||
|
switch v.Opcode() {
|
||||||
|
case llvm.IntToPtr:
|
||||||
|
// Whether a constant inttoptr is nil is easy to
|
||||||
|
// determine.
|
||||||
|
operand := v.Operand(0)
|
||||||
|
if operand.IsConstant() {
|
||||||
|
return operand.ZExtValue() == 0, true
|
||||||
|
}
|
||||||
|
case llvm.BitCast, llvm.GetElementPtr:
|
||||||
|
// These const instructions are just a kind of wrappers for the
|
||||||
|
// underlying pointer.
|
||||||
|
return isPointerNil(v.Operand(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !v.IsAConstantPointerNull().IsNil() {
|
||||||
|
// A constant pointer null is always null, of course.
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
return false, false // not valid
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче