Files
clang-p2996/llvm/test/Transforms/InstSimplify/vscale.ll
Sanjay Patel 3d3c0ed932 [InstSimplify] fold extractelement of splat with variable extract index
We already have a fold for variable index with constant vector,
but if we can determine a scalar splat value, then it does not
matter whether that value is constant or not.

We overlooked this fold in D102404 and earlier patches,
but the fixed vector variant is shown in:
https://llvm.org/PR50817

Alive2 agrees on that:
https://alive2.llvm.org/ce/z/HpijPC

The same logic applies to scalable vectors.

Differential Revision: https://reviews.llvm.org/D104867
2021-07-05 08:19:40 -04:00

220 lines
8.4 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instsimplify -S -verify | FileCheck %s
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Vector Operations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; insertelement
define <vscale x 4 x i32> @insertelement_idx_undef(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @insertelement_idx_undef(
; CHECK-NEXT: ret <vscale x 4 x i32> poison
;
%r = insertelement <vscale x 4 x i32> %a, i32 5, i64 undef
ret <vscale x 4 x i32> %r
}
define <vscale x 4 x i32> @insertelement_value_undef(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @insertelement_value_undef(
; CHECK-NEXT: [[R:%.*]] = insertelement <vscale x 4 x i32> [[A:%.*]], i32 undef, i64 0
; CHECK-NEXT: ret <vscale x 4 x i32> [[R]]
;
%r = insertelement <vscale x 4 x i32> %a, i32 undef, i64 0
ret <vscale x 4 x i32> %r
}
define <vscale x 4 x i32> @insertelement_idx_maybe_out_of_bound(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @insertelement_idx_maybe_out_of_bound(
; CHECK-NEXT: [[R:%.*]] = insertelement <vscale x 4 x i32> [[A:%.*]], i32 5, i64 4
; CHECK-NEXT: ret <vscale x 4 x i32> [[R]]
;
%r = insertelement <vscale x 4 x i32> %a, i32 5, i64 4
ret <vscale x 4 x i32> %r
}
define <vscale x 4 x i32> @insertelement_idx_large_bound(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @insertelement_idx_large_bound(
; CHECK-NEXT: [[R:%.*]] = insertelement <vscale x 4 x i32> [[A:%.*]], i32 5, i64 12345
; CHECK-NEXT: ret <vscale x 4 x i32> [[R]]
;
%r = insertelement <vscale x 4 x i32> %a, i32 5, i64 12345
ret <vscale x 4 x i32> %r
}
define <vscale x 4 x i32> @insert_extract_element_same_vec_idx_1(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @insert_extract_element_same_vec_idx_1(
; CHECK-NEXT: ret <vscale x 4 x i32> [[A:%.*]]
;
%v = extractelement <vscale x 4 x i32> %a, i64 1
%r = insertelement <vscale x 4 x i32> %a, i32 %v, i64 1
ret <vscale x 4 x i32> %r
}
define <vscale x 4 x i32> @insertelement_inline_to_ret() {
; CHECK-LABEL: @insertelement_inline_to_ret(
; CHECK-NEXT: ret <vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 0)
;
%i = insertelement <vscale x 4 x i32> undef, i32 1, i32 0
ret <vscale x 4 x i32> %i
}
define <vscale x 4 x i32> @insertelement_shufflevector_inline_to_ret() {
; CHECK-LABEL: @insertelement_shufflevector_inline_to_ret(
; CHECK-NEXT: ret <vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 0), <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer)
;
%i = insertelement <vscale x 4 x i32> undef, i32 1, i32 0
%i2 = shufflevector <vscale x 4 x i32> %i, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
ret <vscale x 4 x i32> %i2
}
; extractelement
define i32 @extractelement_idx_undef(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @extractelement_idx_undef(
; CHECK-NEXT: ret i32 poison
;
%r = extractelement <vscale x 4 x i32> %a, i64 undef
ret i32 %r
}
define i32 @extractelement_vec_undef(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @extractelement_vec_undef(
; CHECK-NEXT: ret i32 undef
;
%r = extractelement <vscale x 4 x i32> undef, i64 1
ret i32 %r
}
define i32 @extractelement_idx_maybe_out_of_bound(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @extractelement_idx_maybe_out_of_bound(
; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[A:%.*]], i64 4
; CHECK-NEXT: ret i32 [[R]]
;
%r = extractelement <vscale x 4 x i32> %a, i64 4
ret i32 %r
}
define i32 @extractelement_idx_large_bound(<vscale x 4 x i32> %a) {
; CHECK-LABEL: @extractelement_idx_large_bound(
; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[A:%.*]], i64 12345
; CHECK-NEXT: ret i32 [[R]]
;
%r = extractelement <vscale x 4 x i32> %a, i64 12345
ret i32 %r
}
define i32 @insert_extract_element_same_vec_idx_2() {
; CHECK-LABEL: @insert_extract_element_same_vec_idx_2(
; CHECK-NEXT: ret i32 1
;
%v = insertelement <vscale x 4 x i32> undef, i32 1, i64 4
%r = extractelement <vscale x 4 x i32> %v, i64 4
ret i32 %r
}
define i32 @insert_extract_element_same_vec_idx_3() {
; CHECK-LABEL: @insert_extract_element_same_vec_idx_3(
; CHECK-NEXT: ret i32 1
;
%r = extractelement <vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i64 4), i64 4
ret i32 %r
}
define i32 @insert_extract_element_same_vec_idx_4() {
; CHECK-LABEL: @insert_extract_element_same_vec_idx_4(
; CHECK-NEXT: ret i32 1
;
%r = extractelement <vscale x 4 x i32> insertelement (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 4), i32 2, i64 3), i64 4
ret i32 %r
}
; more complicated expressions
define <vscale x 2 x i1> @cmp_le_smax_always_true(<vscale x 2 x i64> %x) {
; CHECK-LABEL: @cmp_le_smax_always_true(
; CHECK-NEXT: ret <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer)
;
%cmp = icmp sle <vscale x 2 x i64> %x, shufflevector (<vscale x 2 x i64> insertelement (<vscale x 2 x i64> undef, i64 9223372036854775807, i32 0), <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer)
ret <vscale x 2 x i1> %cmp
}
define <vscale x 4 x float> @bitcast() {
; CHECK-LABEL: @bitcast(
; CHECK-NEXT: ret <vscale x 4 x float> bitcast (<vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 0), <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer) to <vscale x 4 x float>)
;
%i1 = insertelement <vscale x 4 x i32> undef, i32 1, i32 0
%i2 = shufflevector <vscale x 4 x i32> %i1, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
%i3 = bitcast <vscale x 4 x i32> %i2 to <vscale x 4 x float>
ret <vscale x 4 x float> %i3
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Memory Access and Addressing Operations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; getelementptr
define <vscale x 4 x i32*> @getelementptr_constant_foldable_1() {
; CHECK-LABEL: @getelementptr_constant_foldable_1(
; CHECK-NEXT: ret <vscale x 4 x i32*> zeroinitializer
;
%ptr = getelementptr i32, <vscale x 4 x i32*> zeroinitializer, <vscale x 4 x i64> undef
ret <vscale x 4 x i32*> %ptr
}
define <vscale x 4 x <vscale x 4 x i32>*> @getelementptr_constant_foldable_2() {
; CHECK-LABEL: @getelementptr_constant_foldable_2(
; CHECK-NEXT: ret <vscale x 4 x <vscale x 4 x i32>*> zeroinitializer
;
%ptr = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* null, <vscale x 4 x i64> undef
ret <vscale x 4 x <vscale x 4 x i32>*> %ptr
}
; fold getelementptr P, 0 -> P.
define <vscale x 4 x i32>* @getelementptr_constant_foldable_3() {
; CHECK-LABEL: @getelementptr_constant_foldable_3(
; CHECK-NEXT: ret <vscale x 4 x i32>* null
;
%ptr = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* null, i64 0
ret <vscale x 4 x i32>* %ptr
}
define <vscale x 4 x i32>* @getelementptr_not_constant_foldable(i64 %x) {
; CHECK-LABEL: @getelementptr_not_constant_foldable(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* null, i64 [[X:%.*]]
; CHECK-NEXT: ret <vscale x 4 x i32>* [[PTR]]
;
%ptr = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* null, i64 %x
ret <vscale x 4 x i32>* %ptr
}
; Check GEP's result is known to be non-null.
define i1 @getelementptr_check_non_null(<vscale x 16 x i8>* %ptr) {
; CHECK-LABEL: @getelementptr_check_non_null(
; CHECK-NEXT: ret i1 false
;
%x = getelementptr inbounds <vscale x 16 x i8>, <vscale x 16 x i8>* %ptr, i32 1
%cmp = icmp eq <vscale x 16 x i8>* %x, null
ret i1 %cmp
}
define i32 @extractelement_splat_constant_index(i32 %v) {
; CHECK-LABEL: @extractelement_splat_constant_index(
; CHECK-NEXT: ret i32 [[V:%.*]]
;
%in = insertelement <vscale x 4 x i32> undef, i32 %v, i32 0
%splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
%r = extractelement <vscale x 4 x i32> %splat, i32 1
ret i32 %r
}
define i32 @extractelement_splat_variable_index(i32 %v, i32 %idx) {
; CHECK-LABEL: @extractelement_splat_variable_index(
; CHECK-NEXT: ret i32 [[V:%.*]]
;
%in = insertelement <vscale x 4 x i32> undef, i32 %v, i32 0
%splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
%r = extractelement <vscale x 4 x i32> %splat, i32 %idx
ret i32 %r
}