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

[DAGCombiner] Handle extending EXTRACT_VECTOR_ELTs in calculateByteProvider #83963

Conversation

lukel97
Copy link
Contributor

@lukel97 lukel97 commented Mar 5, 2024

An EXTRACT_VECTOR_ELT can extend the element to the width of its result type, leaving the high bits undefined. Previously if we attempted to query the bytes in these high bits we would recurse and hit an assertion. This fixes it by bailing if the index is outside of the vector element size.

I think the assertion Index < ByteWidth may still be incorrect, since ByteWidth is calculated from Op.getValueSizeInBits(). I believe this should be Op.getScalarValueSizeInBits() whenever VectorIndex is set since we're querying the element now, not the vector. But I couldn't think of a test case to trigger it. It can be addressed in a follow-up patch.

Fixes #83920

…ovider

An EXTRACT_VECTOR_ELT can extend the element to the width of its result type,
leaving the high bits undefined. Previously if we attempted to query the bytes
in these high bits we would recurse and hit an assertion. This fixes it by
bailing if the index is outside of the vector element size.

I think the assertion Index < ByteWidth may still be incorrect, since ByteWidth
is calculated from Op.getValueSizeInBits(). I believe this should be
Op.getScalarValueSizeInBits() whenever VectorIndex is set since we're querying
the element now, not the vector. But I couldn't think of a test case to trigger
it. It can be addressed in a follow-up patch.

Fixes llvm#83920
@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label Mar 5, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 5, 2024

@llvm/pr-subscribers-llvm-selectiondag

Author: Luke Lau (lukel97)

Changes

An EXTRACT_VECTOR_ELT can extend the element to the width of its result type, leaving the high bits undefined. Previously if we attempted to query the bytes in these high bits we would recurse and hit an assertion. This fixes it by bailing if the index is outside of the vector element size.

I think the assertion Index < ByteWidth may still be incorrect, since ByteWidth is calculated from Op.getValueSizeInBits(). I believe this should be Op.getScalarValueSizeInBits() whenever VectorIndex is set since we're querying the element now, not the vector. But I couldn't think of a test case to trigger it. It can be addressed in a follow-up patch.

Fixes #83920


Full diff: https://github.com/llvm/llvm-project/pull/83963.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+4)
  • (added) llvm/test/CodeGen/RISCV/rvv/pr83920.ll (+17)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 33ada3655dc731..f160dde25d26bf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -8627,6 +8627,10 @@ calculateByteProvider(SDValue Op, unsigned Index, unsigned Depth,
     if (NarrowBitWidth % 8 != 0)
       return std::nullopt;
     uint64_t NarrowByteWidth = NarrowBitWidth / 8;
+    // EXTRACT_VECTOR_ELT can extend the element type to the width of the return
+    // type, leaving the high bits undefined.
+    if (Index >= NarrowByteWidth)
+      return std::nullopt;
 
     // Check to see if the position of the element in the vector corresponds
     // with the byte we are trying to provide for. In the case of a vector of
diff --git a/llvm/test/CodeGen/RISCV/rvv/pr83920.ll b/llvm/test/CodeGen/RISCV/rvv/pr83920.ll
new file mode 100644
index 00000000000000..058417629c9c4e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/pr83920.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc < %s -mtriple=riscv64 -mattr=+v -verify-machineinstrs | FileCheck %s
+
+define i8 @or_load_combine(ptr %p) {
+; CHECK-LABEL: or_load_combine:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-NEXT:    vle8.v v8, (a0)
+; CHECK-NEXT:    vmv.x.s a0, v8
+; CHECK-NEXT:    ori a0, a0, 1
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <2 x i8>, ptr %p
+  %1 = extractelement <2 x i8> %0, i64 0
+  %2 = or i8 %1, 1
+  ret i8 %2
+}

@lukel97
Copy link
Contributor Author

lukel97 commented Mar 5, 2024

For reference, this was the failing assertion that I believe needs to be adjusted to handle the vector case:

https://github.com/llvm/llvm-project/blob/0c4736338596d6e527e286b7b551af4bb8b63a55/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp#L8555-L8560

@arsenm arsenm requested a review from jrbyrnes March 5, 2024 09:59
Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

Is the mirror change needed for insert_vector_elt?

llvm/test/CodeGen/RISCV/rvv/pr83920.ll Outdated Show resolved Hide resolved
llvm/test/CodeGen/RISCV/rvv/pr83920.ll Outdated Show resolved Hide resolved
@lukel97
Copy link
Contributor Author

lukel97 commented Mar 5, 2024

Is the mirror change needed for insert_vector_elt?

No, it doesn't seem to be handled in calculateByteProvider.

@lukel97 lukel97 merged commit a668846 into llvm:main Mar 5, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DAGCombiner][RISC-V] DAGCombiner.cpp:8692: Assertion `Index < ByteWidth && "invalid index requested"' failed.
3 participants