Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Omit asserts if condition can be proven statically #685

Merged
merged 1 commit into from Jul 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/builtins.ts
Expand Up @@ -2090,6 +2090,52 @@ export function compileCall(
let type = compiler.currentType;
compiler.currentType = type.nonNullableType;

// if the assertion can be proven statically, omit it
if (getExpressionId(arg0 = module.precomputeExpression(arg0)) == ExpressionId.Const) {
switch (getExpressionType(arg0)) {
case NativeType.I32: {
if (getConstValueI32(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
case NativeType.I64: {
if (getConstValueI64Low(arg0) != 0 || getConstValueI64High(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
case NativeType.F32: {
if (getConstValueF32(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
case NativeType.F64: {
if (getConstValueF64(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
}
}

// return ifTrueish if assertions are disabled
if (compiler.options.noAssert) {
if (contextualType == Type.void) { // simplify if dropped anyway
Expand Down
6 changes: 2 additions & 4 deletions tests/compiler/assert.optimized.wat
@@ -1,10 +1,8 @@
(module
(type $FUNCSIG$v (func))
(memory $0 1)
(data (i32.const 8) "\12\00\00\00\01\00\00\00\01\00\00\00\12\00\00\00a\00s\00s\00e\00r\00t\00.\00t\00s")
(data (i32.const 48) "\18\00\00\00\01\00\00\00\01\00\00\00\18\00\00\00m\00u\00s\00t\00 \00b\00e\00 \00t\00r\00u\00e")
(memory $0 0)
(export "memory" (memory $0))
(func $start (; 0 ;) (type $FUNCSIG$v)
(func $null (; 0 ;) (type $FUNCSIG$v)
nop
)
)
108 changes: 2 additions & 106 deletions tests/compiler/assert.untouched.wat
@@ -1,113 +1,9 @@
(module
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$v (func))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
(memory $0 1)
(data (i32.const 8) "\12\00\00\00\01\00\00\00\01\00\00\00\12\00\00\00a\00s\00s\00e\00r\00t\00.\00t\00s\00")
(data (i32.const 48) "\18\00\00\00\01\00\00\00\01\00\00\00\18\00\00\00m\00u\00s\00t\00 \00b\00e\00 \00t\00r\00u\00e\00")
(memory $0 0)
(table $0 1 funcref)
(elem (i32.const 0) $null)
(export "memory" (memory $0))
(start $start)
(func $start:assert (; 1 ;) (type $FUNCSIG$v)
(local $0 i32)
i32.const 1
i32.eqz
if
i32.const 0
i32.const 24
i32.const 1
i32.const 0
call $~lib/builtins/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 24
i32.const 2
i32.const 0
call $~lib/builtins/abort
unreachable
end
i32.const 1
i32.const 0
i32.gt_u
i32.eqz
if
i32.const 0
i32.const 24
i32.const 3
i32.const 0
call $~lib/builtins/abort
unreachable
end
f64.const 0.5
f64.const 0
f64.eq
if
i32.const 0
i32.const 24
i32.const 4
i32.const 0
call $~lib/builtins/abort
unreachable
end
f64.const 0.5
f64.const 0.4
f64.gt
i32.eqz
if
i32.const 0
i32.const 24
i32.const 5
i32.const 0
call $~lib/builtins/abort
unreachable
end
i64.const 4294967296
i64.eqz
if
i32.const 0
i32.const 24
i32.const 6
i32.const 0
call $~lib/builtins/abort
unreachable
end
i64.const 4294967296
i64.const 1
i64.gt_s
i32.eqz
if
i32.const 0
i32.const 24
i32.const 7
i32.const 0
call $~lib/builtins/abort
unreachable
end
i32.const 1
local.tee $0
if (result i32)
local.get $0
else
i32.const 64
i32.const 24
i32.const 10
i32.const 5
call $~lib/builtins/abort
unreachable
end
i32.eqz
if
unreachable
end
)
(func $start (; 2 ;) (type $FUNCSIG$v)
call $start:assert
)
(func $null (; 3 ;) (type $FUNCSIG$v)
(func $null (; 0 ;) (type $FUNCSIG$v)
)
)