[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / CodeGenPrepare / X86 / vec-shift.ll
blobb69a00a24edc08cef605f49b640c9207b6cd6f01
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -codegenprepare -mtriple=x86_64-- -mattr=avx -S < %s | FileCheck %s --check-prefixes=ALL,AVX
3 ; RUN: opt -codegenprepare -mtriple=x86_64-- -mattr=avx2 -S < %s | FileCheck %s --check-prefixes=ALL,AVX2
4 ; RUN: opt -codegenprepare -mtriple=x86_64-- -mattr=avx -S -enable-debugify < %s 2>&1 | FileCheck %s -check-prefix=DEBUG
6 define <4 x i32> @vector_variable_shift_right(<4 x i1> %cond, <4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
7 ; AVX-LABEL: @vector_variable_shift_right(
8 ; AVX-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> zeroinitializer
9 ; AVX-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> undef, <4 x i32> zeroinitializer
10 ; AVX-NEXT:    [[SEL:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
11 ; AVX-NEXT:    [[TMP1:%.*]] = lshr <4 x i32> [[Z:%.*]], [[SPLAT1]]
12 ; AVX-NEXT:    [[TMP2:%.*]] = lshr <4 x i32> [[Z]], [[SPLAT2]]
13 ; AVX-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[COND]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
14 ; AVX-NEXT:    ret <4 x i32> [[TMP3]]
16 ; AVX2-LABEL: @vector_variable_shift_right(
17 ; AVX2-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> zeroinitializer
18 ; AVX2-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> undef, <4 x i32> zeroinitializer
19 ; AVX2-NEXT:    [[SEL:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
20 ; AVX2-NEXT:    [[SH:%.*]] = lshr <4 x i32> [[Z:%.*]], [[SEL]]
21 ; AVX2-NEXT:    ret <4 x i32> [[SH]]
23   %splat1 = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer
24   %splat2 = shufflevector <4 x i32> %y, <4 x i32> undef, <4 x i32> zeroinitializer
25   %sel = select <4 x i1> %cond, <4 x i32> %splat1, <4 x i32> %splat2
26   %sh = lshr <4 x i32> %z, %sel
27   ret <4 x i32> %sh
30 ; PR37428 - https://bugs.llvm.org/show_bug.cgi?id=37428
32 define void @vector_variable_shift_left_loop(i32* nocapture %arr, i8* nocapture readonly %control, i32 %count, i32 %amt0, i32 %amt1, i32 %x) {
33 ; AVX-LABEL: @vector_variable_shift_left_loop(
34 ; AVX-NEXT:  entry:
35 ; AVX-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[COUNT:%.*]], 0
36 ; AVX-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[COUNT]] to i64
37 ; AVX-NEXT:    br i1 [[CMP16]], label [[VECTOR_PH:%.*]], label [[EXIT:%.*]]
38 ; AVX:       vector.ph:
39 ; AVX-NEXT:    [[N_VEC:%.*]] = and i64 [[WIDE_TRIP_COUNT]], 4294967292
40 ; AVX-NEXT:    [[SPLATINSERT18:%.*]] = insertelement <4 x i32> undef, i32 [[AMT0:%.*]], i32 0
41 ; AVX-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLATINSERT18]], <4 x i32> undef, <4 x i32> zeroinitializer
42 ; AVX-NEXT:    [[SPLATINSERT20:%.*]] = insertelement <4 x i32> undef, i32 [[AMT1:%.*]], i32 0
43 ; AVX-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLATINSERT20]], <4 x i32> undef, <4 x i32> zeroinitializer
44 ; AVX-NEXT:    [[SPLATINSERT22:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 0
45 ; AVX-NEXT:    br label [[VECTOR_BODY:%.*]]
46 ; AVX:       vector.body:
47 ; AVX-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
48 ; AVX-NEXT:    [[TMP0:%.*]] = shufflevector <4 x i32> [[SPLATINSERT20]], <4 x i32> undef, <4 x i32> zeroinitializer
49 ; AVX-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[SPLATINSERT18]], <4 x i32> undef, <4 x i32> zeroinitializer
50 ; AVX-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[SPLATINSERT22]], <4 x i32> undef, <4 x i32> zeroinitializer
51 ; AVX-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[CONTROL:%.*]], i64 [[INDEX]]
52 ; AVX-NEXT:    [[TMP4:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>*
53 ; AVX-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i8>, <4 x i8>* [[TMP4]], align 1
54 ; AVX-NEXT:    [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
55 ; AVX-NEXT:    [[TMP6:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
56 ; AVX-NEXT:    [[TMP7:%.*]] = shl <4 x i32> [[TMP2]], [[TMP1]]
57 ; AVX-NEXT:    [[TMP8:%.*]] = shl <4 x i32> [[TMP2]], [[TMP0]]
58 ; AVX-NEXT:    [[TMP9:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP7]], <4 x i32> [[TMP8]]
59 ; AVX-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i32, i32* [[ARR:%.*]], i64 [[INDEX]]
60 ; AVX-NEXT:    [[TMP11:%.*]] = bitcast i32* [[TMP10]] to <4 x i32>*
61 ; AVX-NEXT:    store <4 x i32> [[TMP9]], <4 x i32>* [[TMP11]], align 4
62 ; AVX-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 4
63 ; AVX-NEXT:    [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
64 ; AVX-NEXT:    br i1 [[TMP12]], label [[EXIT]], label [[VECTOR_BODY]]
65 ; AVX:       exit:
66 ; AVX-NEXT:    ret void
68 ; AVX2-LABEL: @vector_variable_shift_left_loop(
69 ; AVX2-NEXT:  entry:
70 ; AVX2-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[COUNT:%.*]], 0
71 ; AVX2-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[COUNT]] to i64
72 ; AVX2-NEXT:    br i1 [[CMP16]], label [[VECTOR_PH:%.*]], label [[EXIT:%.*]]
73 ; AVX2:       vector.ph:
74 ; AVX2-NEXT:    [[N_VEC:%.*]] = and i64 [[WIDE_TRIP_COUNT]], 4294967292
75 ; AVX2-NEXT:    [[SPLATINSERT18:%.*]] = insertelement <4 x i32> undef, i32 [[AMT0:%.*]], i32 0
76 ; AVX2-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLATINSERT18]], <4 x i32> undef, <4 x i32> zeroinitializer
77 ; AVX2-NEXT:    [[SPLATINSERT20:%.*]] = insertelement <4 x i32> undef, i32 [[AMT1:%.*]], i32 0
78 ; AVX2-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLATINSERT20]], <4 x i32> undef, <4 x i32> zeroinitializer
79 ; AVX2-NEXT:    [[SPLATINSERT22:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 0
80 ; AVX2-NEXT:    [[SPLAT3:%.*]] = shufflevector <4 x i32> [[SPLATINSERT22]], <4 x i32> undef, <4 x i32> zeroinitializer
81 ; AVX2-NEXT:    br label [[VECTOR_BODY:%.*]]
82 ; AVX2:       vector.body:
83 ; AVX2-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
84 ; AVX2-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[CONTROL:%.*]], i64 [[INDEX]]
85 ; AVX2-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to <4 x i8>*
86 ; AVX2-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i8>, <4 x i8>* [[TMP1]], align 1
87 ; AVX2-NEXT:    [[TMP2:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
88 ; AVX2-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
89 ; AVX2-NEXT:    [[TMP4:%.*]] = shl <4 x i32> [[SPLAT3]], [[TMP3]]
90 ; AVX2-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARR:%.*]], i64 [[INDEX]]
91 ; AVX2-NEXT:    [[TMP6:%.*]] = bitcast i32* [[TMP5]] to <4 x i32>*
92 ; AVX2-NEXT:    store <4 x i32> [[TMP4]], <4 x i32>* [[TMP6]], align 4
93 ; AVX2-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 4
94 ; AVX2-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
95 ; AVX2-NEXT:    br i1 [[TMP7]], label [[EXIT]], label [[VECTOR_BODY]]
96 ; AVX2:       exit:
97 ; AVX2-NEXT:    ret void
99 entry:
100   %cmp16 = icmp sgt i32 %count, 0
101   %wide.trip.count = zext i32 %count to i64
102   br i1 %cmp16, label %vector.ph, label %exit
104 vector.ph:
105   %n.vec = and i64 %wide.trip.count, 4294967292
106   %splatinsert18 = insertelement <4 x i32> undef, i32 %amt0, i32 0
107   %splat1 = shufflevector <4 x i32> %splatinsert18, <4 x i32> undef, <4 x i32> zeroinitializer
108   %splatinsert20 = insertelement <4 x i32> undef, i32 %amt1, i32 0
109   %splat2 = shufflevector <4 x i32> %splatinsert20, <4 x i32> undef, <4 x i32> zeroinitializer
110   %splatinsert22 = insertelement <4 x i32> undef, i32 %x, i32 0
111   %splat3 = shufflevector <4 x i32> %splatinsert22, <4 x i32> undef, <4 x i32> zeroinitializer
112   br label %vector.body
114 vector.body:
115   %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
116   %0 = getelementptr inbounds i8, i8* %control, i64 %index
117   %1 = bitcast i8* %0 to <4 x i8>*
118   %wide.load = load <4 x i8>, <4 x i8>* %1, align 1
119   %2 = icmp eq <4 x i8> %wide.load, zeroinitializer
120   %3 = select <4 x i1> %2, <4 x i32> %splat1, <4 x i32> %splat2
121   %4 = shl <4 x i32> %splat3, %3
122   %5 = getelementptr inbounds i32, i32* %arr, i64 %index
123   %6 = bitcast i32* %5 to <4 x i32>*
124   store <4 x i32> %4, <4 x i32>* %6, align 4
125   %index.next = add i64 %index, 4
126   %7 = icmp eq i64 %index.next, %n.vec
127   br i1 %7, label %exit, label %vector.body
129 exit:
130   ret void
133 ; Check that every instruction inserted by -codegenprepare has a debug location.
134 ; DEBUG: CheckModuleDebugify: PASS