-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CodeGen] Allow negative frame indicies in Register class. #164459
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
Changes from 3 commits
dc95302
7b2fcda
478c945
695baef
29bf5cd
a871d1f
e6a016a
b30b8ea
00fa7fb
0d3cc18
98162f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| #define LLVM_CODEGEN_REGISTER_H | ||
|
|
||
| #include "llvm/MC/MCRegister.h" | ||
| #include "llvm/Support/MathExtras.h" | ||
| #include <cassert> | ||
|
|
||
| namespace llvm { | ||
|
|
@@ -35,19 +36,23 @@ class Register { | |
| // DenseMapInfo<unsigned> uses -1u and -2u. | ||
| static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF, | ||
| "Reg isn't large enough to hold full range."); | ||
| static constexpr unsigned FirstStackSlot = 1u << 30; | ||
| static_assert(FirstStackSlot >= MCRegister::LastPhysicalReg); | ||
| static constexpr unsigned MaxFrameIndexBitwidth = 30; | ||
| static constexpr unsigned StackSlotZero = 1u << MaxFrameIndexBitwidth; | ||
| static constexpr const unsigned StackSlotMask = StackSlotZero - 1; | ||
| static_assert(StackSlotZero >= MCRegister::LastPhysicalReg); | ||
| static constexpr unsigned VirtualRegFlag = 1u << 31; | ||
|
|
||
| /// Return true if this is a stack slot. | ||
| constexpr bool isStack() const { | ||
| return Register::FirstStackSlot <= Reg && Reg < Register::VirtualRegFlag; | ||
| return Register::StackSlotZero <= Reg && Reg < Register::VirtualRegFlag; | ||
| } | ||
|
|
||
| /// Convert a non-negative frame index to a stack slot register value. | ||
| static Register index2StackSlot(int FI) { | ||
| assert(FI >= 0 && "Cannot hold a negative frame index."); | ||
| return Register(FI + Register::FirstStackSlot); | ||
| unsigned FIMasked = FI & Register::StackSlotMask; | ||
| assert(isUInt<30>(FIMasked) && | ||
| "Frame index must be at most 30 bit as an unsigned integer"); | ||
| return Register(FIMasked | Register::StackSlotZero); | ||
| } | ||
|
|
||
| /// Return true if the specified register number is in | ||
|
|
@@ -87,7 +92,8 @@ class Register { | |
| /// Compute the frame index from a register value representing a stack slot. | ||
| int stackSlotIndex() const { | ||
| assert(isStack() && "Not a stack slot"); | ||
| return static_cast<int>(Reg - Register::FirstStackSlot); | ||
| return static_cast<int>( | ||
| SignExtend64<MaxFrameIndexBitwidth>(Reg & Register::StackSlotMask)); | ||
|
||
| } | ||
|
|
||
| constexpr operator unsigned() const { return Reg; } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| //===- RegisterTest.cpp -----------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "llvm/CodeGen/Register.h" | ||
| #include "gtest/gtest.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| namespace { | ||
| TEST(RegisterTest, Idx2StackSlot) { | ||
| ASSERT_EQ(Register::index2StackSlot(0), Register::StackSlotZero); | ||
| ASSERT_EQ(Register::index2StackSlot(-1), | ||
| Register::StackSlotZero | Register::StackSlotMask); | ||
| ASSERT_EQ(Register::index2StackSlot(Register::StackSlotMask), | ||
| Register::StackSlotZero | Register::StackSlotMask); | ||
| ASSERT_EQ(Register::index2StackSlot(1), Register::StackSlotZero | 1); | ||
mgudim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| TEST(RegisterTest, StackSlotIndex) { | ||
| Register Reg; | ||
mgudim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| std::vector<int64_t> FIs = {0, 1 - 1, (1 << 29) - 1, -(1 << 29)}; | ||
mgudim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
mgudim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| for (int64_t FI : FIs) { | ||
| Reg = Register::index2StackSlot(FI); | ||
mgudim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ASSERT_EQ(Reg.stackSlotIndex(), FI); | ||
mgudim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } // end namespace | ||
Uh oh!
There was an error while loading. Please reload this page.