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

[PowerPC] Mask constant operands in ValueBit tracking #67653

Merged
merged 2 commits into from
Feb 6, 2024

Conversation

ecnelises
Copy link
Member

@ecnelises ecnelises commented Sep 28, 2023

In IR or C code, shift amount larger than value size is undefined
behavior. But in practice, backend lowering for shift_parts produces
add/sub of shift amounts, thus constant shift amounts might be
negative or larger than value size, which depends on ISA definition.

PowerPC ISA says, the lowest 7 bits (6 bits for 32-bit instruction)
will be taken, and if the highest among them is 1, result will be
zero, otherwise the low 6 bits (or 5 on 32-bit) are used as shift
amount.

This commit emulates the behavior and avoids array overflow in bit
permutation's value bits calculator.

Fixes #59074

; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s --check-prefix=LE64
; RUN: llc -mtriple=powerpcle-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s --check-prefix=LE32
; RUN: llc -mtriple=powerpc64-ibm-aix -mcpu=pwr7 < %s | FileCheck %s --check-prefix=BE64
; RUN: llc -mtriple=powerpc-ibm-aix -mcpu=pwr7 < %s | FileCheck %s --check-prefix=BE32
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-mcpu=pwr8 touches another codepath (such instructions are not generated, so only crash on -mcpu=pwr7).

The crash comes from constant shift amounts of srl_parts, which only presents after splitting v2i128 into v1i128 (from the subtraction parts).

@jacobly0
Copy link
Contributor

jacobly0 commented Feb 1, 2024

I was going to report the following bug, but since it is already fixed by this change, maybe this even simpler repro would be useful to add as a test since it doesn't involve any vectors:

target triple = "powerpc"
define i64 @entry(ptr) {
  store i6 0, ptr %0
  %2 = load i8, ptr %0
  %3 = and i8 %2, 63
  %4 = zext i8 %3 to i64
  %5 = shl i64 1, %4
  ret i64 %5
}
$ llc -version
LLVM (http://llvm.org/):
  LLVM version 17.0.6
  DEBUG build with assertions.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: znver4
$ llc repro.ll
llc: llvm/include/llvm/ADT/SmallVector.h:294: reference llvm::SmallVectorTemplateCommon<(anonymous namespace)::BitPermutationSelector::ValueBit>::operator[](size_type) [T = (anonymous namespace)::BitPermutationSelector::ValueBit]: Assertion `idx < size()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: llc repro.ll
1.	Running pass 'Function Pass Manager' on module 'repro.ll'.
2.	Running pass 'PowerPC DAG->DAG Pattern Instruction Selection' on function '@entry'
 #0 0x00007f2d0ca6dd06 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) llvm/lib/Support/Unix/Signals.inc:602:11
 #1 0x00007f2d0ca6e25b PrintStackTraceSignalHandler(void*) llvm/lib/Support/Unix/Signals.inc:675:1
 #2 0x00007f2d0ca6c403 llvm::sys::RunSignalHandlers() llvm/lib/Support/Signals.cpp:104:5
 #3 0x00007f2d0ca6e941 SignalHandler(int) llvm/lib/Support/Unix/Signals.inc:413:1
 #4 0x00007f2d0c2b5c90 (/usr/lib64/libc.so.6+0x39c90)
 #5 0x00007f2d0c30619c (/usr/lib64/libc.so.6+0x8a19c)
 #6 0x00007f2d0c2b5be2 gsignal (/usr/lib64/libc.so.6+0x39be2)
 #7 0x00007f2d0c29e4ed abort (/usr/lib64/libc.so.6+0x224ed)
 #8 0x00007f2d0c29e415 (/usr/lib64/libc.so.6+0x22415)
 #9 0x00007f2d0c2ae542 (/usr/lib64/libc.so.6+0x32542)
#10 0x00007f2d15445499 llvm::SmallVectorTemplateCommon<(anonymous namespace)::BitPermutationSelector::ValueBit, void>::operator[](unsigned long) llvm/include/llvm/ADT/SmallVector.h:0:5
#11 0x00007f2d1544344f (anonymous namespace)::BitPermutationSelector::getValueBits(llvm::SDValue, unsigned int) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1645:19
#12 0x00007f2d1544395a (anonymous namespace)::BitPermutationSelector::getValueBits(llvm::SDValue, unsigned int) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1694:30
#13 0x00007f2d15441e59 (anonymous namespace)::BitPermutationSelector::Select(llvm::SDNode*) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:2825:9
#14 0x00007f2d154385ec (anonymous namespace)::PPCDAGToDAGISel::tryBitPermutation(llvm::SDNode*) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:4096:17
#15 0x00007f2d154211c6 (anonymous namespace)::PPCDAGToDAGISel::Select(llvm::SDNode*) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:5195:7
#16 0x00007f2d111cdbba llvm::SelectionDAGISel::DoInstructionSelection() llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1179:5
#17 0x00007f2d111ccbb5 llvm::SelectionDAGISel::CodeGenAndEmitDAG() llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:950:3
#18 0x00007f2d111cb459 llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, false, true>, llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, false, true>, bool&) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:702:1
#19 0x00007f2d111cae34 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1705:11
#20 0x00007f2d111c82c0 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:482:3
#21 0x00007f2d15420d26 (anonymous namespace)::PPCDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:173:7
#22 0x00007f2d1046b4cc llvm::MachineFunctionPass::runOnFunction(llvm::Function&) llvm/lib/CodeGen/MachineFunctionPass.cpp:91:8
#23 0x00007f2d0d427815 llvm::FPPassManager::runOnFunction(llvm::Function&) llvm/lib/IR/LegacyPassManager.cpp:1435:23
#24 0x00007f2d0d42cd4f llvm::FPPassManager::runOnModule(llvm::Module&) llvm/lib/IR/LegacyPassManager.cpp:1481:16
#25 0x00007f2d0d42818b (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) llvm/lib/IR/LegacyPassManager.cpp:1550:23
#26 0x00007f2d0d427c9a llvm::legacy::PassManagerImpl::run(llvm::Module&) llvm/lib/IR/LegacyPassManager.cpp:535:16
#27 0x00007f2d0d42d051 llvm::legacy::PassManager::run(llvm::Module&) llvm/lib/IR/LegacyPassManager.cpp:1677:3
#28 0x000055e89c38576f compileModule(char**, llvm::LLVMContext&) llvm/tools/llc/llc.cpp:754:41
#29 0x000055e89c3839d5 main llvm/tools/llc/llc.cpp:416:13
#30 0x00007f2d0c29feea (/usr/lib64/libc.so.6+0x23eea)
#31 0x00007f2d0c29ffa5 __libc_start_main (/usr/lib64/libc.so.6+0x23fa5)
#32 0x000055e89c3831a1 _start (bin/llc+0x2e1a1)
Aborted (core dumped)

Copy link
Collaborator

@bzEq bzEq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nit.

llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Show resolved Hide resolved
@Rexicon226
Copy link

Thank you @bzEq for the quick response. Would it be possible to backport this into 18?

In IR or C code, left/right shift amount larger than value size is
undefined behavior. But in practise, backend lowering for
srl_parts/sra_parts/shl_parts produces add/sub of shift amounts, thus
constant shift amounts might be negative or larger than value size. And
the lowering depends on behavior in ISA.

PowerPC ISA says, the lowest 7 bits (6 bits if in 32-bit instruction)
will be taken, and if the highest among them is 1, result will be zero,
otherwise the low 6 bits (or 5 on 32-bit) are used as shift amount.

This patch emulates the behavior and avoids array overflow in bit
permutation's value bits calculator.
@ecnelises ecnelises merged commit 292d9e8 into llvm:main Feb 6, 2024
4 checks passed
@ecnelises ecnelises deleted the shiftamt_mask branch February 20, 2024 02:38
@ecnelises
Copy link
Member Author

Thank you @bzEq for the quick response. Would it be possible to backport this into 18?

/cherry-pick 292d9e8

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 20, 2024

Thank you @bzEq for the quick response. Would it be possible to backport this into 18?

/cherry-pick 292d9e8

Error: Command failed due to missing milestone.

@ecnelises ecnelises added this to the LLVM 18.X Release milestone Feb 20, 2024
@ecnelises
Copy link
Member Author

/cherry-pick 292d9e8

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 20, 2024

Failed to create pull request for issue67653 https://github.com/llvm/llvm-project/actions/runs/7967856697

@ecnelises
Copy link
Member Author

/cherry-pick 292d9e8

llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Feb 20, 2024
In IR or C code, shift amount larger than value size is undefined
behavior. But in practice, backend lowering for shift_parts produces
add/sub of shift amounts, thus constant shift amounts might be
negative or larger than value size, which depends on ISA definition.

PowerPC ISA says, the lowest 7 bits (6 bits for 32-bit instruction)
will be taken, and if the highest among them is 1, result will be
zero, otherwise the low 6 bits (or 5 on 32-bit) are used as shift
amount.

This commit emulates the behavior and avoids array overflow in bit
permutation's value bits calculator.

(cherry picked from commit 292d9e8)
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 20, 2024

/pull-request #82301

llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Feb 20, 2024
In IR or C code, shift amount larger than value size is undefined
behavior. But in practice, backend lowering for shift_parts produces
add/sub of shift amounts, thus constant shift amounts might be
negative or larger than value size, which depends on ISA definition.

PowerPC ISA says, the lowest 7 bits (6 bits for 32-bit instruction)
will be taken, and if the highest among them is 1, result will be
zero, otherwise the low 6 bits (or 5 on 32-bit) are used as shift
amount.

This commit emulates the behavior and avoids array overflow in bit
permutation's value bits calculator.

(cherry picked from commit 292d9e8)
@pointhex pointhex mentioned this pull request May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

[PowerPC] Backend crash due to index out of bound when lshr / shl i128 vector after sub
5 participants