diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 33ada3655dc73..f160dde25d26b 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 0000000000000..319f0bd9ef1cd --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/pr83920.ll @@ -0,0 +1,16 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc < %s -mtriple=riscv64 -mattr=+v | FileCheck %s + +define i8 @or_load_combine(ptr %p) { +; CHECK-LABEL: or_load_combine: +; CHECK: # %bb.0: +; 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 + %load = load <2 x i8>, ptr %p + %extract = extractelement <2 x i8> %load, i64 0 + %or = or i8 %extract, 1 + ret i8 %or +}