blob: 23ab5fcc00fcc6461ca05e2cd68bca6fc9067ab7 [file] [log] [blame]
#include "dataflow/graph.h"
#include "dataflow/node.h"
#include "parser/wat-parser.h"
#include "wasm.h"
#include "gtest/gtest.h"
using namespace wasm;
using namespace wasm::DataFlow;
class DataflowTest : public ::testing::Test {
protected:
void parseWast(Module& wasm, const std::string& wast) {
auto parsed = WATParser::parseModule(wasm, wast);
if (auto* err = parsed.getErr()) {
Fatal() << err->msg << "\n";
}
}
};
// Regression test for https://github.com/WebAssembly/binaryen/issues/8273
// In the no-else case, mergeIf arguments were swapped: the initial state
// (before the if body) was paired with the ifTrue condition and the
// afterIfTrue state was paired with ifFalse. This test verifies the fix.
TEST_F(DataflowTest, IfNoElseMergeOrder) {
auto moduleText = R"wasm(
(module
(func $test (param $cond i32)
(local $x i32)
(local.set $x (i32.const 10))
(if (local.get $cond)
(then
(local.set $x (i32.const 42))
)
)
(drop (local.get $x))
)
)
)wasm";
Module wasm;
parseWast(wasm, moduleText);
auto* func = wasm.getFunction("test");
Graph graph;
graph.build(func, &wasm);
// Find the phi node for local $x (index 1).
Node* phi = nullptr;
for (auto& node : graph.nodes) {
if (node->isPhi() && node->index == 1) {
phi = node.get();
break;
}
}
ASSERT_NE(phi, nullptr) << "Expected a phi node for local $x";
// Phi structure: values[0] = block, values[1] = ifTrue value,
// values[2] = ifFalse value.
ASSERT_EQ(phi->values.size(), 3u);
auto* ifTrueNode = phi->values[1];
auto* ifFalseNode = phi->values[2];
ASSERT_TRUE(ifTrueNode->isConst());
ASSERT_TRUE(ifFalseNode->isConst());
int32_t ifTrueValue = ifTrueNode->expr->cast<Const>()->value.geti32();
int32_t ifFalseValue = ifFalseNode->expr->cast<Const>()->value.geti32();
// When condition is true (body ran), $x should be 42.
EXPECT_EQ(ifTrueValue, 42)
<< "When condition is TRUE, phi should select 42 (set in ifTrue body)";
// When condition is false (body skipped), $x should be 10 (initial value).
EXPECT_EQ(ifFalseValue, 10)
<< "When condition is FALSE, phi should select 10 (initial value)";
}