enabling <coroutine> from std library for folly when c++ version is 20
[hiphop-php.git] / hphp / runtime / test / vasm-simplify-test.cpp
blobda6f9efcbad58a129de769704435ff2b977f7c56
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/containers.h"
18 #include "hphp/runtime/vm/jit/vasm.h"
19 #include "hphp/runtime/vm/jit/vasm-gen.h"
20 #include "hphp/runtime/vm/jit/vasm-instr.h"
21 #include "hphp/runtime/vm/jit/vasm-print.h"
22 #include "hphp/runtime/vm/jit/vasm-unit.h"
24 #include <folly/portability/GTest.h>
26 namespace HPHP::jit {
28 namespace {
30 // Strip extraneous whitespace from vasm code strings.
31 std::string stripWhitespace(std::string str) {
32 if (str.length() > 1 && str[0] == '\n' && str[1] == ' ') {
33 str.erase(0, 2);
35 size_t spc, pos = 0;
36 while((spc = str.find(" ", pos)) != std::string::npos) {
37 str.erase(spc, 1);
38 pos = spc;
40 pos = 0;
41 while((spc = str.find(" \n", pos)) != std::string::npos) {
42 str.erase(spc, 1);
43 pos = spc;
45 pos = 0;
46 while((spc = str.find("\n ", pos)) != std::string::npos) {
47 str.erase(spc+1, 1);
48 pos = spc;
50 return str;
53 void testSetccXor() {
55 Vunit unit;
56 unit.entry = unit.makeBlock(AreaIndex::Main, 1);
57 Vout v(unit, unit.entry);
59 auto sf = v.makeReg();
60 auto dst = v.makeReg();
61 auto xdst = v.makeReg();
62 v << movl{unit.makeConst(42u), sf};
63 v << setcc{CC_Z, sf, dst};
64 v << xorbi{1, dst, xdst, v.makeReg()};
66 simplify(unit);
68 // Test that setcc/xor pair is collapsed.
69 EXPECT_EQ(
70 "B0 main (1)\n"
71 "movl %131(42l) => %128\n"
72 "setcc NE, %128 => %130\n",
73 stripWhitespace(show(unit))
78 Vunit unit;
79 unit.entry = unit.makeBlock(AreaIndex::Main, 1);
80 Vout v(unit, unit.entry);
82 auto sf = v.makeReg();
83 auto dst = v.makeReg();
84 auto xdst = v.makeReg();
85 v << movl{unit.makeConst(42u), sf};
86 v << setcc{CC_Z, sf, dst};
87 v << xorbi{1, dst, xdst, v.makeReg()};
88 v << movl{dst, v.makeReg()};
90 simplify(unit);
92 // Test that setcc/xor pair is not collapsed when setcc result
93 // has more than one use.
94 EXPECT_EQ(
95 "B0 main (1)\n"
96 "movl %131(42l) => %128\n"
97 "setcc E, %128 => %129\n"
98 "xorbi 1, %129 => %130, %132\n"
99 "movl %129 => %133\n",
100 stripWhitespace(show(unit))
105 Vunit unit;
106 unit.entry = unit.makeBlock(AreaIndex::Main, 1);
107 Vout v(unit, unit.entry);
109 auto sf = v.makeReg();
110 auto dst = v.makeReg();
111 auto xdst = v.makeReg();
112 v << movl{unit.makeConst(42u), sf};
113 v << setcc{CC_NZ, sf, dst};
114 v << xorbi{1, dst, xdst, v.makeReg()};
116 simplify(unit);
118 // Check that setcc/xor pair is collapsed with different condition.
119 EXPECT_EQ(
120 "B0 main (1)\n"
121 "movl %131(42l) => %128\n"
122 "setcc E, %128 => %130\n",
123 stripWhitespace(show(unit))
128 Vunit unit;
129 unit.entry = unit.makeBlock(AreaIndex::Main, 1);
130 Vout v(unit, unit.entry);
132 auto sf = v.makeReg();
133 auto dst = v.makeReg();
134 v << movl{unit.makeConst(42u), sf};
135 v << setcc{CC_NZ, sf, dst};
137 simplify(unit);
139 // Make sure that setcc with no xor doesn't cause a buffer overrun.
140 EXPECT_EQ(
141 "B0 main (1)\n"
142 "movl %130(42l) => %128\n"
143 "setcc NE, %128 => %129\n",
144 stripWhitespace(show(unit))
149 Vunit unit;
150 unit.entry = unit.makeBlock(AreaIndex::Main, 1);
151 Vout v(unit, unit.entry);
153 auto sf = v.makeReg();
154 auto dst = v.makeReg();
155 auto xdst = v.makeReg();
156 v << movl{unit.makeConst(42u), sf};
157 v << setcc{CC_NZ, sf, dst};
158 v << xorbi{2, dst, xdst, v.makeReg()};
160 simplify(unit);
162 // Make sure that setcc/xor with an non-1 xor constant is skipped.
163 EXPECT_EQ(
164 "B0 main (1)\n"
165 "movl %131(42l) => %128\n"
166 "setcc NE, %128 => %129\n"
167 "xorbi 2, %129 => %130, %132\n",
168 stripWhitespace(show(unit))
173 Vunit unit;
174 unit.entry = unit.makeBlock(AreaIndex::Main, 1);
175 Vout v(unit, unit.entry);
177 auto sf = v.makeReg();
178 auto dst = v.makeReg();
179 auto xdst = v.makeReg();
180 auto xsf = v.makeReg();
181 v << movl{unit.makeConst(42u), sf};
182 v << setcc{CC_NZ, sf, dst};
183 v << xorbi{1, dst, xdst, xsf};
184 v << movl{xsf, v.makeReg()};
186 simplify(unit);
188 // Make sure that setcc/xor with xor status flags being used is skipped.
189 EXPECT_EQ(
190 "B0 main (1)\n"
191 "movl %132(42l) => %128\n"
192 "setcc NE, %128 => %129\n"
193 "xorbi 1, %129 => %130, %131\n"
194 "movl %131 => %133\n",
195 stripWhitespace(show(unit))
202 TEST(Vasm, Simplifier) {
203 testSetccXor();