diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9a7fdc8bd..035262d5a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -24,7 +24,6 @@ detect_stray_source_files("${sources}" ".")
 set(contracts_sources
     contracts/AuctionRegistrar.cpp
     contracts/ContractInterface.h
-    contracts/FixedFeeRegistrar.cpp
     contracts/Wallet.cpp
 )
 detect_stray_source_files("${contracts_sources}" "contracts/")
diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp
deleted file mode 100644
index b0f2ba8f6..000000000
--- a/test/contracts/FixedFeeRegistrar.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-	This file is part of solidity.
-
-	solidity is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	solidity is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with solidity.  If not, see .
-*/
-// SPDX-License-Identifier: GPL-3.0
-/**
- * @author Christian 
- * @date 2015
- * Tests for a fixed fee registrar contract.
- */
-
-#include 
-
-#include 
-#include 
-#include 
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable:4535) // calling _set_se_translator requires /EHa
-#endif
-#include 
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-#include 
-
-using namespace std;
-using namespace solidity;
-using namespace solidity::util;
-using namespace solidity::test;
-
-namespace solidity::frontend::test
-{
-
-namespace
-{
-
-static char const* registrarCode = R"DELIMITER(
-//sol FixedFeeRegistrar
-// Simple global registrar with fixed-fee reservations.
-// @authors:
-//   Gav Wood 
-
-pragma solidity >=0.4.0 <0.9.0;
-
-abstract contract Registrar {
-	event Changed(string indexed name);
-
-	function owner(string memory _name) public virtual view returns (address o_owner);
-	function addr(string memory _name) public virtual view returns (address o_address);
-	function subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);
-	function content(string memory _name) public virtual view returns (bytes32 o_content);
-}
-
-contract FixedFeeRegistrar is Registrar {
-	struct Record {
-		address addr;
-		address subRegistrar;
-		bytes32 content;
-		address owner;
-	}
-
-	modifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }
-
-	function reserve(string memory _name) public payable {
-		Record storage rec = m_record(_name);
-		if (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {
-			rec.owner = msg.sender;
-			emit Changed(_name);
-		}
-	}
-	function disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {
-		delete m_recordData[uint(keccak256(bytes(_name))) / 8];
-		if (!_refund.send(c_fee))
-			revert();
-		emit Changed(_name);
-	}
-	function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {
-		m_record(_name).owner = _newOwner;
-		emit Changed(_name);
-	}
-	function setAddr(string memory _name, address _a) onlyrecordowner(_name) public {
-		m_record(_name).addr = _a;
-		emit Changed(_name);
-	}
-	function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {
-		m_record(_name).subRegistrar = _registrar;
-		emit Changed(_name);
-	}
-	function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {
-		m_record(_name).content = _content;
-		emit Changed(_name);
-	}
-
-	function record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
-		Record storage rec = m_record(_name);
-		o_addr = rec.addr;
-		o_subRegistrar = rec.subRegistrar;
-		o_content = rec.content;
-		o_owner = rec.owner;
-	}
-	function addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }
-	function subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }
-	function content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }
-	function owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }
-
-	Record[2**253] m_recordData;
-	function m_record(string memory _name) view internal returns (Record storage o_record) {
-		return m_recordData[uint(keccak256(bytes(_name))) / 8];
-	}
-	uint constant c_fee = 69 ether;
-}
-)DELIMITER";
-
-static LazyInit s_compiledRegistrar;
-
-class RegistrarTestFramework: public SolidityExecutionFramework
-{
-protected:
-	void deployRegistrar()
-	{
-		bytes const& compiled = s_compiledRegistrar.init([&]{
-			return compileContract(registrarCode, "FixedFeeRegistrar");
-		});
-
-		sendMessage(compiled, true);
-		BOOST_REQUIRE(m_transactionSuccessful);
-		BOOST_REQUIRE(!m_output.empty());
-	}
-	u256 const m_fee = u256("69000000000000000000");
-};
-
-}
-
-/// This is a test suite that tests optimised code!
-BOOST_FIXTURE_TEST_SUITE(SolidityFixedFeeRegistrar, RegistrarTestFramework)
-
-BOOST_AUTO_TEST_CASE(creation)
-{
-	deployRegistrar();
-}
-
-BOOST_AUTO_TEST_CASE(reserve)
-{
-	// Test that reserving works and fee is taken into account.
-	deployRegistrar();
-	string name[] = {"abc", "def", "ghi"};
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name[0])) == encodeArgs());
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[0])) == encodeArgs(account(0)));
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee + 1, encodeDyn(name[1])) == encodeArgs());
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[1])) == encodeArgs(account(0)));
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee - 1, encodeDyn(name[2])) == encodeArgs());
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[2])) == encodeArgs(h160{}));
-}
-
-BOOST_AUTO_TEST_CASE(double_reserve)
-{
-	// Test that it is not possible to re-reserve from a different address.
-	deployRegistrar();
-	string name = "abc";
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(account(0)));
-
-	sendEther(account(1), 100 * ether);
-	m_sender = account(1);
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(account(0)));
-}
-
-BOOST_AUTO_TEST_CASE(properties)
-{
-	// Test setting and retrieving  the various properties works.
-	deployRegistrar();
-	string names[] = {"abc", "def", "ghi"};
-	size_t addr = 0x9872543;
-	size_t count = 1;
-	for (string const& name: names)
-	{
-		addr++;
-		m_sender = account(0);
-		sendEther(account(count), 100 * ether);
-		m_sender = account(count);
-		h160 owner = m_sender;
-		// setting by sender works
-		BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
-		BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(owner));
-		BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), u256(addr), u256(name.length()), name) == encodeArgs());
-		BOOST_CHECK(callContractFunction("addr(string)", encodeDyn(name)) == encodeArgs(addr));
-		BOOST_CHECK(callContractFunction("setSubRegistrar(string,address)", u256(0x40), addr + 20, u256(name.length()), name) == encodeArgs());
-		BOOST_CHECK(callContractFunction("subRegistrar(string)", encodeDyn(name)) == encodeArgs(addr + 20));
-		BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), addr + 90, u256(name.length()), name) == encodeArgs());
-		BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(addr + 90));
-		count++;
-		// but not by someone else
-		m_sender = account(0);
-		sendEther(account(count), 100 * ether);
-		m_sender = account(count);
-		BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(owner));
-		BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), addr + 1, u256(name.length()), name) == encodeArgs());
-		BOOST_CHECK(callContractFunction("addr(string)", encodeDyn(name)) == encodeArgs(addr));
-		BOOST_CHECK(callContractFunction("setSubRegistrar(string,address)", u256(0x40), addr + 20 + 1, u256(name.length()), name) == encodeArgs());
-		BOOST_CHECK(callContractFunction("subRegistrar(string)", encodeDyn(name)) == encodeArgs(addr + 20));
-		BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), addr + 90 + 1, u256(name.length()), name) == encodeArgs());
-		BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(addr + 90));
-		count++;
-	}
-}
-
-BOOST_AUTO_TEST_CASE(transfer)
-{
-	deployRegistrar();
-	string name = "abc";
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
-	BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), account(0), u256(name.length()), name) == encodeArgs());
-	BOOST_CHECK(callContractFunction("transfer(string,address)", u256(0x40), u256(555), u256(name.length()), name) == encodeArgs());
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(u256(555)));
-	BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(account(0)));
-}
-
-BOOST_AUTO_TEST_CASE(disown)
-{
-	deployRegistrar();
-	string name = "abc";
-	BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
-	BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), account(0), u256(name.length()), name) == encodeArgs());
-	BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), u256(124), u256(name.length()), name) == encodeArgs());
-	BOOST_CHECK(callContractFunction("setSubRegistrar(string,address)", u256(0x40), u256(125), u256(name.length()), name) == encodeArgs());
-
-	BOOST_CHECK_EQUAL(balanceAt(h160(0x124)), 0);
-	BOOST_CHECK(callContractFunction("disown(string,address)", u256(0x40), u256(0x124), name.size(), name) == encodeArgs());
-	BOOST_CHECK_EQUAL(balanceAt(h160(0x124)), m_fee);
-
-	BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(u256(0)));
-	BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(u256(0)));
-	BOOST_CHECK(callContractFunction("addr(string)", encodeDyn(name)) == encodeArgs(u256(0)));
-	BOOST_CHECK(callContractFunction("subRegistrar(string)", encodeDyn(name)) == encodeArgs(u256(0)));
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // end namespaces
diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol
new file mode 100644
index 000000000..b6d8f4399
--- /dev/null
+++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol
@@ -0,0 +1,111 @@
+//sol FixedFeeRegistrar
+// Simple global registrar with fixed-fee reservations.
+// @authors:
+//   Gav Wood 
+
+pragma solidity >=0.4.0 <0.9.0;
+
+abstract contract Registrar {
+	event Changed(string indexed name);
+
+	function owner(string memory _name) public virtual view returns (address o_owner);
+	function addr(string memory _name) public virtual view returns (address o_address);
+	function subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);
+	function content(string memory _name) public virtual view returns (bytes32 o_content);
+}
+
+contract FixedFeeRegistrar is Registrar {
+	struct Record {
+		address addr;
+		address subRegistrar;
+		bytes32 content;
+		address owner;
+	}
+
+	modifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }
+
+	function reserve(string memory _name) public payable {
+		Record storage rec = m_record(_name);
+		if (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {
+			rec.owner = msg.sender;
+			emit Changed(_name);
+		}
+	}
+	function disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {
+		delete m_recordData[uint(keccak256(bytes(_name))) / 8];
+		if (!_refund.send(c_fee))
+			revert();
+		emit Changed(_name);
+	}
+	function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {
+		m_record(_name).owner = _newOwner;
+		emit Changed(_name);
+	}
+	function setAddr(string memory _name, address _a) onlyrecordowner(_name) public {
+		m_record(_name).addr = _a;
+		emit Changed(_name);
+	}
+	function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {
+		m_record(_name).subRegistrar = _registrar;
+		emit Changed(_name);
+	}
+	function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {
+		m_record(_name).content = _content;
+		emit Changed(_name);
+	}
+
+	function record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
+		Record storage rec = m_record(_name);
+		o_addr = rec.addr;
+		o_subRegistrar = rec.subRegistrar;
+		o_content = rec.content;
+		o_owner = rec.owner;
+	}
+	function addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }
+	function subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }
+	function content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }
+	function owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }
+
+	Record[2**253] m_recordData;
+	function m_record(string memory _name) view internal returns (Record storage o_record) {
+		return m_recordData[uint(keccak256(bytes(_name))) / 8];
+	}
+	uint constant c_fee = 69 ether;
+}
+// ====
+// compileViaYul: also
+// ----
+// constructor()
+// gas irOptimized: 544916
+// gas legacy: 942808
+// gas legacyOptimized: 492291
+// reserve(string), 69 ether: 0x20, 3, "abc" ->
+// gas irOptimized: 45527
+// gas legacy: 46242
+// gas legacyOptimized: 45491
+// owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012
+// reserve(string), 70 ether: 0x20, 3, "def" ->
+// owner(string): 0x20, 3, "def" -> 0x1212121212121212121212121212120000000012
+// reserve(string), 68 ether: 0x20, 3, "ghi" ->
+// owner(string): 0x20, 3, "ghi" -> 0
+// account: 1 -> 0x1212121212121212121212121212120000001012
+// reserve(string), 69 ether: 0x20, 3, "abc" ->
+// owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012
+// account: 0 -> 0x1212121212121212121212121212120000000012
+// setContent(string,bytes32): 0x40, 0, 3, "abc" ->
+// transfer(string,address): 0x40, 555, 3, "abc" ->
+// owner(string): 0x20, 3, "abc" -> 555
+// content(string): 0x20, 3, "abc" -> 0x00
+// setContent(string,bytes32): 0x40, 333, 3, "def" ->
+// setAddr(string,address): 0x40, 124, 3, "def" ->
+// setSubRegistrar(string,address): 0x40, 125, 3, "def" ->
+// content(string): 0x20, 3, "def" -> 333
+// addr(string): 0x20, 3, "def" -> 124
+// subRegistrar(string): 0x20, 3, "def" -> 125
+// balance: 0x124 -> 0
+// disown(string,address): 0x40, 0x124, 3, "def" ->
+// balance: 0x124 -> 0
+// owner(string): 0x20, 3, "def" -> 0
+// content(string): 0x20, 3, "def" -> 0
+// addr(string): 0x20, 3, "def" -> 0
+// subRegistrar(string): 0x20, 3, "def" -> 0