[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / SLPVectorizer / X86 / pr35497.ll
blobbdb37b28d58ce36d26d27113c09ebb505def40e5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
4 %class.1 = type { %class.2 }
5 %class.2 = type { %"class.3" }
6 %"class.3" = type { %"struct.1", i64 }
7 %"struct.1" = type { [8 x i64] }
9 $_ZN1C10SwitchModeEv = comdat any
11 ; Function Attrs: uwtable
12 define void @_ZN1C10SwitchModeEv() local_unnamed_addr #0 comdat align 2 {
13 ; CHECK-LABEL: @_ZN1C10SwitchModeEv(
14 ; CHECK-NEXT:  for.body.lr.ph.i:
15 ; CHECK-NEXT:    [[OR_1:%.*]] = or i64 undef, 1
16 ; CHECK-NEXT:    store i64 [[OR_1]], i64* undef, align 8
17 ; CHECK-NEXT:    [[FOO_1:%.*]] = getelementptr inbounds [[CLASS_1:%.*]], %class.1* undef, i64 0, i32 0, i32 0, i32 0, i32 0, i64 0
18 ; CHECK-NEXT:    [[FOO_2:%.*]] = getelementptr inbounds [[CLASS_1]], %class.1* undef, i64 0, i32 0, i32 0, i32 0, i32 0, i64 1
19 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[FOO_1]] to <2 x i64>*
20 ; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
21 ; CHECK-NEXT:    [[BAR5:%.*]] = load i64, i64* undef, align 8
22 ; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i64> undef, i64 [[OR_1]], i32 0
23 ; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> [[TMP2]], i64 [[BAR5]], i32 1
24 ; CHECK-NEXT:    [[TMP4:%.*]] = and <2 x i64> [[TMP3]], [[TMP1]]
25 ; CHECK-NEXT:    [[BAR3:%.*]] = getelementptr inbounds [[CLASS_2:%.*]], %class.2* undef, i64 0, i32 0, i32 0, i32 0, i64 0
26 ; CHECK-NEXT:    [[BAR4:%.*]] = getelementptr inbounds [[CLASS_2]], %class.2* undef, i64 0, i32 0, i32 0, i32 0, i64 1
27 ; CHECK-NEXT:    [[TMP5:%.*]] = bitcast i64* [[BAR3]] to <2 x i64>*
28 ; CHECK-NEXT:    store <2 x i64> [[TMP4]], <2 x i64>* [[TMP5]], align 8
29 ; CHECK-NEXT:    ret void
31 for.body.lr.ph.i:
32   %or.1 = or i64 undef, 1
33   store i64 %or.1, i64* undef, align 8
34   %foo.1 = getelementptr inbounds %class.1, %class.1* undef, i64 0, i32 0, i32 0, i32 0, i32 0, i64 0
35   %foo.3 = load i64, i64* %foo.1, align 8
36   %foo.2 = getelementptr inbounds %class.1, %class.1* undef, i64 0, i32 0, i32 0, i32 0, i32 0, i64 1
37   %foo.4 = load i64, i64* %foo.2, align 8
38   %bar5 = load i64, i64* undef, align 8
39   %and.2 = and i64 %or.1, %foo.3
40   %and.1 = and i64 %bar5, %foo.4
41   %bar3 = getelementptr inbounds %class.2, %class.2* undef, i64 0, i32 0, i32 0, i32 0, i64 0
42   store i64 %and.2, i64* %bar3, align 8
43   %bar4 = getelementptr inbounds %class.2, %class.2* undef, i64 0, i32 0, i32 0, i32 0, i64 1
44   store i64 %and.1, i64* %bar4, align 8
45   ret void
48 ; Function Attrs: norecurse nounwind uwtable
49 define void @pr35497() local_unnamed_addr #0 {
50 ; CHECK-LABEL: @pr35497(
51 ; CHECK-NEXT:  entry:
52 ; CHECK-NEXT:    [[TMP0:%.*]] = load i64, i64* undef, align 1
53 ; CHECK-NEXT:    [[ADD:%.*]] = add i64 undef, undef
54 ; CHECK-NEXT:    store i64 [[ADD]], i64* undef, align 1
55 ; CHECK-NEXT:    [[ARRAYIDX2_1:%.*]] = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 5
56 ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> undef, i64 [[TMP0]], i32 1
57 ; CHECK-NEXT:    [[TMP2:%.*]] = shl <2 x i64> [[TMP1]], <i64 2, i64 2>
58 ; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i64> [[TMP2]], <i64 20, i64 20>
59 ; CHECK-NEXT:    [[ARRAYIDX2_2:%.*]] = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 4
60 ; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw <2 x i64> [[TMP3]], zeroinitializer
61 ; CHECK-NEXT:    [[ARRAYIDX2_5:%.*]] = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 1
62 ; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x i64> [[TMP4]], i32 1
63 ; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i64> undef, i64 [[TMP5]], i32 0
64 ; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <2 x i64> [[TMP6]], i64 [[ADD]], i32 1
65 ; CHECK-NEXT:    [[TMP8:%.*]] = shl <2 x i64> [[TMP7]], <i64 2, i64 2>
66 ; CHECK-NEXT:    [[TMP9:%.*]] = and <2 x i64> [[TMP8]], <i64 20, i64 20>
67 ; CHECK-NEXT:    [[ARRAYIDX2_6:%.*]] = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 0
68 ; CHECK-NEXT:    [[TMP10:%.*]] = bitcast i64* [[ARRAYIDX2_6]] to <2 x i64>*
69 ; CHECK-NEXT:    store <2 x i64> [[TMP4]], <2 x i64>* [[TMP10]], align 1
70 ; CHECK-NEXT:    [[TMP11:%.*]] = lshr <2 x i64> [[TMP4]], <i64 6, i64 6>
71 ; CHECK-NEXT:    [[TMP12:%.*]] = add nuw nsw <2 x i64> [[TMP9]], [[TMP11]]
72 ; CHECK-NEXT:    [[TMP13:%.*]] = bitcast i64* [[ARRAYIDX2_2]] to <2 x i64>*
73 ; CHECK-NEXT:    store <2 x i64> [[TMP12]], <2 x i64>* [[TMP13]], align 1
74 ; CHECK-NEXT:    ret void
76 entry:
77   %0 = load i64, i64* undef, align 1
78   %and = shl i64 %0, 2
79   %shl = and i64 %and, 20
80   %add = add i64 undef, undef
81   store i64 %add, i64* undef, align 1
82   %arrayidx2.1 = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 5
83   %and.1 = shl i64 undef, 2
84   %shl.1 = and i64 %and.1, 20
85   %shr.1 = lshr i64 undef, 6
86   %add.1 = add nuw nsw i64 %shl, %shr.1
87   %arrayidx2.2 = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 4
88   %shr.2 = lshr i64 undef, 6
89   %add.2 = add nuw nsw i64 %shl.1, %shr.2
90   %and.4 = shl i64 %add, 2
91   %shl.4 = and i64 %and.4, 20
92   %arrayidx2.5 = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 1
93   store i64 %add.1, i64* %arrayidx2.5, align 1
94   %and.5 = shl nuw nsw i64 %add.1, 2
95   %shl.5 = and i64 %and.5, 20
96   %shr.5 = lshr i64 %add.1, 6
97   %add.5 = add nuw nsw i64 %shl.4, %shr.5
98   store i64 %add.5, i64* %arrayidx2.1, align 1
99   %arrayidx2.6 = getelementptr inbounds [0 x i64], [0 x i64]* undef, i64 0, i64 0
100   store i64 %add.2, i64* %arrayidx2.6, align 1
101   %shr.6 = lshr i64 %add.2, 6
102   %add.6 = add nuw nsw i64 %shl.5, %shr.6
103   store i64 %add.6, i64* %arrayidx2.2, align 1
104   ret void