Skip to content
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

[WASM] Assertion isReg() && "This is not a register operand!" failed during pass Machine Common Subexpression Elimination #58904

Closed
HazyFish opened this issue Nov 10, 2022 · 5 comments
Assignees

Comments

@HazyFish
Copy link
Contributor

HazyFish commented Nov 10, 2022

Description

When targeting wasm32 / wasm64, the following code crashes the backend during pass Machine Common Subexpression Elimination with assertion isReg() && "This is not a register operand!" failed.

The crash happens specifically when the second operand for urem is -1.
This problem does not exist when targeting aarch64, x86_64, or riscv64.

Minimal Reproduction

https://godbolt.org/z/hKr3jo1s6

Code

define i64 @f() {
BB:
  %A = alloca i64
  %C2 = ptrtoint i64* %A to i64
  %B2 = urem i64 %C2, -1
  ret i64 %B2
}

Stack Trace

llc: /home/henry/aflplusplus-isel/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h:360: llvm::Register llvm::MachineOperand::getReg() const: Assertion `isReg() && "This is not a register operand!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ./llvm-project/build-debug/bin/llc -mtriple=wasm64 ./crash-reports/dagisel-wasm64/1.ll
1.	Running pass 'Function Pass Manager' on module './crash-reports/dagisel-wasm64/1.ll'.
2.	Running pass 'Machine Common Subexpression Elimination' on function '@f'
 #0 0x00000000047ada8a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Unix/Signals.inc:569:11
 #1 0x00000000047adc3b PrintStackTraceSignalHandler(void*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Unix/Signals.inc:636:1
 #2 0x00000000047ac286 llvm::sys::RunSignalHandlers() /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Signals.cpp:104:5
 #3 0x00000000047ae365 SignalHandler(int) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Unix/Signals.inc:407:1
 #4 0x00007f4404fd8980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
 #5 0x00007f4403ec8e87 raise /build/glibc-CVJwZb/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
 #6 0x00007f4403eca7f1 abort /build/glibc-CVJwZb/glibc-2.27/stdlib/abort.c:81:0
 #7 0x00007f4403eba3fa __assert_fail_base /build/glibc-CVJwZb/glibc-2.27/assert/assert.c:89:0
 #8 0x00007f4403eba472 (/lib/x86_64-linux-gnu/libc.so.6+0x30472)
 #9 0x000000000104784c llvm::MachineOperand::getReg() const /home/henry/aflplusplus-isel/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h:0:5
#10 0x0000000003513514 (anonymous namespace)::MachineCSE::PerformTrivialCopyPropagation(llvm::MachineInstr*, llvm::MachineBasicBlock*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp:188:44
#11 0x000000000351221d (anonymous namespace)::MachineCSE::ProcessBlockCSE(llvm::MachineBasicBlock*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp:541:11
#12 0x0000000003510845 (anonymous namespace)::MachineCSE::PerformCSE(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp:790:16
#13 0x00000000035104e3 (anonymous namespace)::MachineCSE::runOnMachineFunction(llvm::MachineFunction&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp:947:14
#14 0x00000000035783e5 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:91:8
#15 0x0000000003c55c66 llvm::FPPassManager::runOnFunction(llvm::Function&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1430:23
#16 0x0000000003c5aa92 llvm::FPPassManager::runOnModule(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1476:16
#17 0x0000000003c56539 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1545:23
#18 0x0000000003c560ad llvm::legacy::PassManagerImpl::run(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:535:16
#19 0x0000000003c5ad71 llvm::legacy::PassManager::run(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1672:3
#20 0x0000000000d38a5c compileModule(char**, llvm::LLVMContext&) /home/henry/aflplusplus-isel/llvm-project/llvm/tools/llc/llc.cpp:737:41
#21 0x0000000000d36e02 main /home/henry/aflplusplus-isel/llvm-project/llvm/tools/llc/llc.cpp:418:13
#22 0x00007f4403eabc87 __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:344:0
#23 0x0000000000d3660a _start (./llvm-project/build-debug/bin/llc+0xd3660a)
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 10, 2022

@llvm/issue-subscribers-backend-webassembly

@HazyFish
Copy link
Contributor Author

The code compiles using LLVM 14 and 15, but fails to compile using main branch

@lukel97
Copy link
Contributor

lukel97 commented Nov 22, 2022

I've bisected the first bad commit to e4b2c52

It looks like it changes the result of instruction selection from

    t2: i64 = I64_EXTEND_U_I32 TargetFrameIndex:i32<0>
  t6: i64 = COPY t2
      t9: i64 = CONST_I64 TargetConstant:i64<0>
        t3: i64 = CONST_I64 TargetConstant:i64<-1>
      t8: i32 = EQ_I64 t6, t3
    t10: i64 = SELECT_I64 t9, t6, t8
    t0: ch = EntryToken
  t5: ch = RETURN t10, t0

to something more like

      t11: i32 = COPY TargetFrameIndex:i32<0>
    t12: i64 = I64_EXTEND_U_I32 t11
    t0: ch,glue = EntryToken
  t5: ch = RETURN t12, t0

Resulting in the MIR:

bb.0 (%ir-block.0):
  liveins: $arguments
  %0:i32 = COPY %stack.0.a
  %1:i64 = I64_EXTEND_U_I32 killed %0:i32, implicit-def dead $arguments
  RETURN killed %1:i64, implicit-def dead $arguments

Further passes (not limited to just machine-cse) then throw that assertion because there's a COPY of a stack frame index.

@tlively
Copy link
Collaborator

tlively commented Nov 22, 2022

@RKSimon, would you be able to take a look at this?

@RKSimon RKSimon self-assigned this Nov 22, 2022
@RKSimon
Copy link
Collaborator

RKSimon commented Nov 22, 2022

The DAG ends up with this:

SelectionDAG has 9 nodes:
  t5: i64 = freeze TargetFrameIndex:i64<0>
    t0: ch,glue = EntryToken
      t7: i32 = setcc t5, Constant:i64<-1>, seteq:ch
    t9: i64 = select t7, Constant:i64<0>, t5
  t4: ch = WebAssemblyISD::RETURN t0, t9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants