[SimplifyLibCalls] Remove useless bits of this tests.
[oota-llvm.git] / test / Transforms / InstCombine / type_pun.ll
1 ; RUN: opt < %s -instcombine -S | FileCheck %s
2
3 ; Ensure that type punning using a union of vector and same-sized array
4 ; generates an extract instead of a shuffle with an uncommon vector size:
5 ;
6 ;   typedef uint32_t v4i32 __attribute__((vector_size(16)));
7 ;   union { v4i32 v; uint32_t a[4]; };
8 ;
9 ; This cleans up behind SROA, which inserts the uncommon vector size when
10 ; cleaning up the alloca/store/GEP/load.
11
12
13 ; Provide legal integer types.
14 target datalayout = "p:32:32"
15
16
17 ; Extracting the zeroth element in an i32 array.
18 define i32 @type_pun_zeroth(<16 x i8> %in) {
19 ; CHECK-LABEL: @type_pun_zeroth(
20 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
21 ; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 0
22 ; CHECK-NEXT: ret i32 %[[EXT]]
23   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
24   %1 = bitcast <4 x i8> %sroa to i32
25   ret i32 %1
26 }
27
28 ; Extracting the first element in an i32 array.
29 define i32 @type_pun_first(<16 x i8> %in) {
30 ; CHECK-LABEL: @type_pun_first(
31 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
32 ; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 1
33 ; CHECK-NEXT: ret i32 %[[EXT]]
34   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
35   %1 = bitcast <4 x i8> %sroa to i32
36   ret i32 %1
37 }
38
39 ; Extracting an i32 that isn't aligned to any natural boundary.
40 define i32 @type_pun_misaligned(<16 x i8> %in) {
41 ; CHECK-LABEL: @type_pun_misaligned(
42 ; CHECK-NEXT: %[[SHUF:.*]] = shufflevector <16 x i8> %in, <16 x i8> undef, <16 x i32> <i32 6, i32 7, i32 8, i32 9, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
43 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %[[SHUF]] to <4 x i32>
44 ; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 0
45 ; CHECK-NEXT: ret i32 %[[EXT]]
46   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 6, i32 7, i32 8, i32 9>
47   %1 = bitcast <4 x i8> %sroa to i32
48   ret i32 %1
49 }
50
51 ; Type punning to an array of pointers.
52 define i32* @type_pun_pointer(<16 x i8> %in) {
53 ; CHECK-LABEL: @type_pun_pointer(
54 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
55 ; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 0
56 ; CHECK-NEXT: %[[I2P:.*]] = inttoptr i32 %[[EXT]] to i32*
57 ; CHECK-NEXT: ret i32* %[[I2P]]
58   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
59   %1 = bitcast <4 x i8> %sroa to i32
60   %2 = inttoptr i32 %1 to i32*
61   ret i32* %2
62 }
63
64 ; Type punning to an array of 32-bit floating-point values.
65 define float @type_pun_float(<16 x i8> %in) {
66 ; CHECK-LABEL: @type_pun_float(
67 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x float>
68 ; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x float> %[[BC]], i32 0
69 ; CHECK-NEXT: ret float %[[EXT]]
70   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
71   %1 = bitcast <4 x i8> %sroa to float
72   ret float %1
73 }
74
75 ; Type punning to an array of 64-bit floating-point values.
76 define double @type_pun_double(<16 x i8> %in) {
77 ; CHECK-LABEL: @type_pun_double(
78 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <2 x double>
79 ; CHECK-NEXT: %[[EXT:.*]] = extractelement <2 x double> %[[BC]], i32 0
80 ; CHECK-NEXT: ret double %[[EXT]]
81   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
82   %1 = bitcast <8 x i8> %sroa to double
83   ret double %1
84 }
85
86 ; Type punning to same-size floating-point and integer values.
87 ; Verify that multiple uses with different bitcast types are properly handled.
88 define { float, i32 } @type_pun_float_i32(<16 x i8> %in) {
89 ; CHECK-LABEL: @type_pun_float_i32(
90 ; CHECK-NEXT: %[[BCI:.*]] = bitcast <16 x i8> %in to <4 x i32>
91 ; CHECK-NEXT: %[[EXTI:.*]] = extractelement <4 x i32> %[[BCI]], i32 0
92 ; CHECK-NEXT: %[[BCF:.*]] = bitcast <16 x i8> %in to <4 x float>
93 ; CHECK-NEXT: %[[EXTF:.*]] = extractelement <4 x float> %[[BCF]], i32 0
94 ; CHECK-NEXT: %1 = insertvalue { float, i32 } undef, float %[[EXTF]], 0
95 ; CHECK-NEXT: %2 = insertvalue { float, i32 } %1, i32 %[[EXTI]], 1
96 ; CHECK-NEXT: ret { float, i32 } %2
97   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
98   %f = bitcast <4 x i8> %sroa to float
99   %i = bitcast <4 x i8> %sroa to i32
100   %1 = insertvalue { float, i32 } undef, float %f, 0
101   %2 = insertvalue { float, i32 } %1, i32 %i, 1
102   ret { float, i32 } %2
103 }
104
105 ; Type punning two i32 values, with control flow.
106 ; Verify that the bitcast is shared and dominates usage.
107 define i32 @type_pun_i32_ctrl(<16 x i8> %in) {
108 ; CHECK-LABEL: @type_pun_i32_ctrl(
109 entry: ; CHECK-NEXT: entry:
110 ; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
111 ; CHECK-NEXT: br
112   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
113   br i1 undef, label %left, label %right
114 left: ; CHECK: left:
115 ; CHECK-NEXT: %[[EXTL:.*]] = extractelement <4 x i32> %[[BC]], i32 0
116 ; CHECK-NEXT: br
117   %lhs = bitcast <4 x i8> %sroa to i32
118   br label %tail
119 right: ; CHECK: right:
120 ; CHECK-NEXT: %[[EXTR:.*]] = extractelement <4 x i32> %[[BC]], i32 0
121 ; CHECK-NEXT: br
122   %rhs = bitcast <4 x i8> %sroa to i32
123   br label %tail
124 tail: ; CHECK: tail:
125 ; CHECK-NEXT: %i = phi i32 [ %[[EXTL]], %left ], [ %[[EXTR]], %right ]
126 ; CHECK-NEXT: ret i32 %i
127   %i = phi i32 [ %lhs, %left ], [ %rhs, %right ]
128   ret i32 %i
129 }
130
131 ; Extracting a type that won't fit in a vector isn't handled. The function
132 ; should stay the same.
133 define i40 @type_pun_unhandled(<16 x i8> %in) {
134 ; CHECK-LABEL: @type_pun_unhandled(
135 ; CHECK-NEXT: %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <5 x i32> <i32 4, i32 5, i32 6, i32 7, i32 8>
136 ; CHECK-NEXT: %1 = bitcast <5 x i8> %sroa to i40
137 ; CHECK-NEXT: ret i40 %1
138   %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <5 x i32> <i32 4, i32 5, i32 6, i32 7, i32 8>
139   %1 = bitcast <5 x i8> %sroa to i40
140   ret i40 %1
141 }