From 93b8849d9f98ef7ed812938ff0b3219819c2be77 Mon Sep 17 00:00:00 2001 From: "taylor.fish" Date: Fri, 24 Jun 2022 18:04:09 +0000 Subject: [Wasm2JS] Fix lowering of i64.extendN_s instructions (#4321) --- src/passes/I64ToI32Lowering.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src') diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index 7a07d946b..11707d4f3 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -539,6 +539,39 @@ struct I64ToI32Lowering : public WalkerPass> { replaceCurrent(result); } + void lowerExtendSInt64(Unary* curr) { + TempVar highBits = getTemp(); + TempVar lowBits = getTemp(); + + // free the temp var + fetchOutParam(curr->value); + + Expression* lowValue = curr->value; + switch (curr->op) { + case ExtendS8Int64: + lowValue = builder->makeUnary(ExtendS8Int32, lowValue); + break; + case ExtendS16Int64: + lowValue = builder->makeUnary(ExtendS16Int32, lowValue); + break; + default: + break; + } + + LocalSet* setLow = builder->makeLocalSet(lowBits, lowValue); + LocalSet* setHigh = builder->makeLocalSet( + highBits, + builder->makeBinary(ShrSInt32, + builder->makeLocalGet(lowBits, Type::i32), + builder->makeConst(int32_t(31)))); + + Block* result = builder->blockify( + setLow, setHigh, builder->makeLocalGet(lowBits, Type::i32)); + + setOutParam(result, std::move(highBits)); + replaceCurrent(result); + } + void lowerWrapInt64(Unary* curr) { // free the temp var fetchOutParam(curr->value); @@ -845,6 +878,9 @@ struct I64ToI32Lowering : public WalkerPass> { case ConvertUInt64ToFloat32: case ConvertUInt64ToFloat64: case ReinterpretInt64: + case ExtendS8Int64: + case ExtendS16Int64: + case ExtendS32Int64: return true; default: return false; @@ -895,6 +931,11 @@ struct I64ToI32Lowering : public WalkerPass> { case ConvertUInt64ToFloat64: lowerConvertIntToFloat(curr); break; + case ExtendS8Int64: + case ExtendS16Int64: + case ExtendS32Int64: + lowerExtendSInt64(curr); + break; case PopcntInt64: WASM_UNREACHABLE("i64.popcnt should already be removed"); default: -- cgit v1.2.3