snu-sf-class / swpp202401

Principles and Practices of Software Development Main Repository
14 stars 4 forks source link

[Project] Backend error: unable to handle programs exceeding MAX_REGISTER #151

Open jhwest1 opened 5 months ago

jhwest1 commented 5 months ago

I found a bug in src/lib/backend/register_allocation.cpp where it raises a segmentation fault error when relocating excessive usage of registers into stack memory. Attached is the LLVM IR program that occurs the bug. I've checked that when ran with constexpr unsigned int MAX_REGISTER = 64U;, the backend produces the 33th register (which parser fails to understand).

test_opt.txt

After some debugging, it seems as the error origins from the function void insertLoadStore() in register_allocation.cpp. in particular the code uint64_t acc = dyn_cast<llvm::ConstantInt>(SP->getArgOperand(0))->getZExtValue(); in the line 485.

%0 = call i64 @const_i64(i64 8192)
%1 = call i64 @"$decr_sp"(i64 %0)
%2 = call i64 @const_i64(i64 0)
%3 = trunc i64 %2 to i32
%4 = call <8 x i32> @vbcast_i32x8(i32 %3)
...

Here llvm::CallInst *SP holds a pointer to %1, so SP->getArgOperand(0) is actually a llvm::CallInst hence dyn_cast<llvm::ConstandInt>(SP->getArgOperand(0)) returns null.

To fix this bug, I have modified the mentioned line into the following code (both in void insertLoadStore() and void insertVectorLoadStore())

uint64_t acc;
if (dyn_cast<llvm::ConstantInt>(SP->getArgOperand(0))) {
    acc = llvm::dyn_cast<llvm::ConstantInt>(SP->getArgOperand(0))->getZExtValue();
} else {
  if (auto *CI = dyn_cast<llvm::CallInst>(SP->getArgOperand(0))) {
    acc = llvm::dyn_cast<llvm::ConstantInt>(CI->getArgOperand(0))->getZExtValue();
  }
}

This fixed the bug for the moment, but I'm unsure if this is the right way to handle it. I would appreciate if you could review this issue!

strikef commented 5 months ago

It does seem to be a bug; this issue will be addressed in the next backend update.