Much of foldLoadsRecursive relies on knowing the size of loaded data, which is not possible for scalable vector types. However, the logic of combining two small loads into one bigger load does not apply for vector types so rather than converting the algorithm to use TypeSize I've simply added an early exit for vectors. Fixes #59510 Differential Revision: https://reviews.llvm.org/D140106
51 lines
2.9 KiB
LLVM
51 lines
2.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
|
|
|
|
; Use the same idoim as X86/or-load.ll @loadCombine_2consecutive to represent a
|
|
; sequence of operations that can be replaced by a single double-width load when
|
|
; using scalar types but whose logic does not apply to fixed length vectors.
|
|
define <8 x i16> @or-load-fixed-length-vector(ptr %p1) {
|
|
; CHECK-LABEL: @or-load-fixed-length-vector(
|
|
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P1:%.*]], i32 1
|
|
; CHECK-NEXT: [[L1:%.*]] = load <8 x i8>, ptr [[P1]], align 1
|
|
; CHECK-NEXT: [[L2:%.*]] = load <8 x i8>, ptr [[P2]], align 1
|
|
; CHECK-NEXT: [[E1:%.*]] = zext <8 x i8> [[L1]] to <8 x i16>
|
|
; CHECK-NEXT: [[E2:%.*]] = zext <8 x i8> [[L2]] to <8 x i16>
|
|
; CHECK-NEXT: [[S2:%.*]] = shl <8 x i16> [[E2]], <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
|
|
; CHECK-NEXT: [[OR:%.*]] = or <8 x i16> [[E1]], [[S2]]
|
|
; CHECK-NEXT: ret <8 x i16> [[OR]]
|
|
;
|
|
%p2 = getelementptr i8, ptr %p1, i32 1
|
|
%l1 = load <8 x i8>, ptr %p1, align 1
|
|
%l2 = load <8 x i8>, ptr %p2, align 1
|
|
%e1 = zext <8 x i8> %l1 to <8 x i16>
|
|
%e2 = zext <8 x i8> %l2 to <8 x i16>
|
|
%s2 = shl <8 x i16> %e2, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
|
|
%or = or <8 x i16> %e1, %s2
|
|
ret <8 x i16> %or
|
|
}
|
|
|
|
; Use the same idoim as X86/or-load.ll @loadCombine_2consecutive to represent a
|
|
; sequence of operations that can be replaced by a single double-width load when
|
|
; using scalar types but whose logic does not apply to scalable length vectors.
|
|
define <vscale x 8 x i16> @or-load-scalable-vector(ptr %p1) {
|
|
; CHECK-LABEL: @or-load-scalable-vector(
|
|
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P1:%.*]], i32 1
|
|
; CHECK-NEXT: [[L1:%.*]] = load <vscale x 8 x i8>, ptr [[P1]], align 1
|
|
; CHECK-NEXT: [[L2:%.*]] = load <vscale x 8 x i8>, ptr [[P2]], align 1
|
|
; CHECK-NEXT: [[E1:%.*]] = zext <vscale x 8 x i8> [[L1]] to <vscale x 8 x i16>
|
|
; CHECK-NEXT: [[E2:%.*]] = zext <vscale x 8 x i8> [[L2]] to <vscale x 8 x i16>
|
|
; CHECK-NEXT: [[S2:%.*]] = shl <vscale x 8 x i16> [[E2]], shufflevector (<vscale x 8 x i16> insertelement (<vscale x 8 x i16> poison, i16 8, i32 0), <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer)
|
|
; CHECK-NEXT: [[OR:%.*]] = or <vscale x 8 x i16> [[E1]], [[S2]]
|
|
; CHECK-NEXT: ret <vscale x 8 x i16> [[OR]]
|
|
;
|
|
%p2 = getelementptr i8, ptr %p1, i32 1
|
|
%l1 = load <vscale x 8 x i8>, ptr %p1, align 1
|
|
%l2 = load <vscale x 8 x i8>, ptr %p2, align 1
|
|
%e1 = zext <vscale x 8 x i8> %l1 to <vscale x 8 x i16>
|
|
%e2 = zext <vscale x 8 x i8> %l2 to <vscale x 8 x i16>
|
|
%s2 = shl <vscale x 8 x i16> %e2, shufflevector (<vscale x 8 x i16> insertelement (<vscale x 8 x i16> poison, i16 8, i32 0), <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer)
|
|
%or = or <vscale x 8 x i16> %e1, %s2
|
|
ret <vscale x 8 x i16> %or
|
|
}
|