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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/builtins.ts
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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)
)
)
Loading