OLD | NEW |
(Empty) | |
| 1 ; RUN: opt -flatten-globals %s -S | FileCheck %s |
| 2 ; RUN: opt -flatten-globals %s -S | FileCheck %s -check-prefix=CLEANED |
| 3 |
| 4 target datalayout = "p:32:32:32" |
| 5 |
| 6 |
| 7 ; Check simple cases |
| 8 |
| 9 @var_i32 = global i32 258 |
| 10 ; CHECK: @var_i32 = global [4 x i8] c"\02\01\00\00" |
| 11 ; CLEANED-NOT: global i32 258 |
| 12 |
| 13 @external_var = external global i32 |
| 14 ; CHECK: @external_var = external global [4 x i8] |
| 15 |
| 16 @zero_init = global i32 0 |
| 17 ; CHECK: @zero_init = global [4 x i8] zeroinitializer |
| 18 |
| 19 @big_zero_init = global [2000 x i8] zeroinitializer |
| 20 ; CHECK: @big_zero_init = global [2000 x i8] zeroinitializer |
| 21 |
| 22 @null_ptr = global i32* null |
| 23 ; CHECK: @null_ptr = global [4 x i8] zeroinitializer |
| 24 |
| 25 @undef_value = global i32 undef |
| 26 ; CHECK: @undef_value = global [4 x i8] zeroinitializer |
| 27 |
| 28 %opaque = type opaque |
| 29 @opaque_extern = external global %opaque |
| 30 ; CHECK: @opaque_extern = external global [0 x i8] |
| 31 |
| 32 |
| 33 ; Check various data types |
| 34 |
| 35 @var_i1 = global i8 1 |
| 36 ; CHECK: @var_i1 = global [1 x i8] c"\01" |
| 37 |
| 38 @var_i8 = global i8 65 |
| 39 ; CHECK: @var_i8 = global [1 x i8] c"A" |
| 40 |
| 41 @var_i16 = global i16 258 |
| 42 ; CHECK: @var_i16 = global [2 x i8] c"\02\01" |
| 43 |
| 44 @var_i64 = global i64 72623859790382856 |
| 45 ; CHECK: @var_i64 = global [8 x i8] c"\08\07\06\05\04\03\02\01" |
| 46 |
| 47 @var_i128 = global i128 1339673755198158349044581307228491536 |
| 48 ; CHECK: @var_i128 = global [16 x i8] c"\10\0F\0E\0D\0C\0B\0A\09\08\07\06\05\04\
03\02\01" |
| 49 |
| 50 ; Check that padding bits come out as zero. |
| 51 @var_i121 = global i121 1339673755198158349044581307228491536 |
| 52 ; CHECK: @var_i121 = global [16 x i8] c"\10\0F\0E\0D\0C\0B\0A\09\08\07\06\05\04\
03\02\01" |
| 53 |
| 54 @var_double = global double 123.456 |
| 55 ; CHECK: @var_double = global [8 x i8] c"w\BE\9F\1A/\DD^@" |
| 56 |
| 57 @var_float = global float 123.0 |
| 58 ; CHECK: @var_float = global [4 x i8] c"\00\00\F6B" |
| 59 |
| 60 |
| 61 ; Check aggregates |
| 62 |
| 63 @padded_struct = global { i8, i8, i32 } { i8 65, i8 66, i32 258 } |
| 64 ; CHECK: @padded_struct = global [8 x i8] c"AB\00\00\02\01\00\00" |
| 65 |
| 66 @packed_struct = global <{ i8, i8, i32 }> <{ i8 67, i8 68, i32 258 }> |
| 67 ; CHECK: @packed_struct = global [6 x i8] c"CD\02\01\00\00" |
| 68 |
| 69 @i8_array = global [6 x i8] c"Hello\00" |
| 70 ; CHECK: @i8_array = global [6 x i8] c"Hello\00" |
| 71 |
| 72 @i16_array = global [3 x i16] [ i16 1, i16 2, i16 3 ] |
| 73 ; CHECK: @i16_array = global [6 x i8] c"\01\00\02\00\03\00" |
| 74 |
| 75 %s = type { i8, i8 } |
| 76 @struct_array = global [2 x %s] [%s { i8 1, i8 2 }, %s { i8 3, i8 4 }] |
| 77 ; CHECK: @struct_array = global [4 x i8] c"\01\02\03\04" |
| 78 |
| 79 @vector = global <2 x i32> <i32 259, i32 520> |
| 80 ; CHECK: @vector = global [8 x i8] c"\03\01\00\00\08\02\00\00" |
| 81 |
| 82 |
| 83 ; Check that various attributes are preserved |
| 84 |
| 85 @constant_var = constant i32 259 |
| 86 ; CHECK: @constant_var = constant [4 x i8] c"\03\01\00\00" |
| 87 |
| 88 @weak_external_var = extern_weak global i32 |
| 89 ; CHECK: @weak_external_var = extern_weak global [4 x i8] |
| 90 |
| 91 @tls_var = external thread_local global i32 |
| 92 ; CHECK: @tls_var = external thread_local global [4 x i8] |
| 93 |
| 94 @aligned_var = global i32 260, align 8 |
| 95 ; CHECK: @aligned_var = global [4 x i8] c"\04\01\00\00", align 8 |
| 96 |
| 97 |
| 98 ; Check alignment handling |
| 99 |
| 100 @implicit_alignment_i32 = global i32 zeroinitializer |
| 101 ; CHECK: @implicit_alignment_i32 = global [4 x i8] zeroinitializer, align 4 |
| 102 |
| 103 @implicit_alignment_double = global double zeroinitializer |
| 104 ; CHECK: @implicit_alignment_double = global [8 x i8] zeroinitializer, align 8 |
| 105 |
| 106 @implicit_alignment_vector = global <16 x i8> zeroinitializer |
| 107 ; CHECK: @implicit_alignment_vector = global [16 x i8] zeroinitializer, align 16 |
| 108 |
| 109 ; FlattenGlobals is not allowed to increase the alignment of the |
| 110 ; variable when an explicit section is specified (although PNaCl does |
| 111 ; not support this attribute). |
| 112 @lower_alignment_section = global i32 0, section "mysection", align 1 |
| 113 ; CHECK: @lower_alignment_section = global [4 x i8] zeroinitializer, section "my
section", align 1 |
| 114 |
| 115 ; FlattenGlobals could increase the alignment when no section is |
| 116 ; specified, but it does not. |
| 117 @lower_alignment = global i32 0, align 1 |
| 118 ; CHECK: @lower_alignment = global [4 x i8] zeroinitializer, align 1 |
| 119 |
| 120 |
| 121 ; Check handling of global references |
| 122 |
| 123 @var1 = external global i32 |
| 124 @var2 = external global i8 |
| 125 |
| 126 %ptrs1 = type { i32*, i8*, i32 } |
| 127 @ptrs1 = global %ptrs1 { i32* @var1, i8* null, i32 259 } |
| 128 ; CHECK: @ptrs1 = global <{ i32, [8 x i8] }> <{ i32 ptrtoint ([4 x i8]* @var1 to
i32), [8 x i8] c"\00\00\00\00\03\01\00\00" }> |
| 129 |
| 130 %ptrs2 = type { i32, i32*, i8* } |
| 131 @ptrs2 = global %ptrs2 { i32 259, i32* @var1, i8* @var2 } |
| 132 ; CHECK: @ptrs2 = global <{ [4 x i8], i32, i32 }> <{ [4 x i8] c"\03\01\00\00", i
32 ptrtoint ([4 x i8]* @var1 to i32), i32 ptrtoint ([1 x i8]* @var2 to i32) }> |
| 133 |
| 134 %ptrs3 = type { i32*, [3 x i8], i8* } |
| 135 @ptrs3 = global %ptrs3 { i32* @var1, [3 x i8] c"foo", i8* @var2 } |
| 136 ; CHECK: @ptrs3 = global <{ i32, [4 x i8], i32 }> <{ i32 ptrtoint ([4 x i8]* @va
r1 to i32), [4 x i8] c"foo\00", i32 ptrtoint ([1 x i8]* @var2 to i32) }> |
| 137 |
| 138 @ptr = global i32* @var1 |
| 139 ; CHECK: @ptr = global i32 ptrtoint ([4 x i8]* @var1 to i32) |
| 140 |
| 141 @func_ptr = global i32* ()* @get_address |
| 142 ; CHECK: @func_ptr = global i32 ptrtoint (i32* ()* @get_address to i32) |
| 143 |
| 144 @block_addr = global i8* blockaddress(@func_with_block, %label) |
| 145 ; CHECK: @block_addr = global i32 ptrtoint (i8* blockaddress(@func_with_block, %
label) to i32) |
| 146 |
| 147 @vector_reloc = global <2 x i32*> <i32* @var1, i32* @var1> |
| 148 ; CHECK: global <{ i32, i32 }> <{ i32 ptrtoint ([4 x i8]* @var1 to i32), i32 ptr
toint ([4 x i8]* @var1 to i32) }> |
| 149 |
| 150 |
| 151 ; Global references with addends |
| 152 |
| 153 @reloc_addend = global i32* getelementptr (%ptrs1* @ptrs1, i32 0, i32 2) |
| 154 ; CHECK: @reloc_addend = global i32 add (i32 ptrtoint (<{ i32, [8 x i8] }>* @ptr
s1 to i32), i32 8) |
| 155 |
| 156 @negative_addend = global %ptrs1* getelementptr (%ptrs1* @ptrs1, i32 -1) |
| 157 ; CHECK: @negative_addend = global i32 add (i32 ptrtoint (<{ i32, [8 x i8] }>* @
ptrs1 to i32), i32 -12) |
| 158 |
| 159 @const_ptr = global i32* getelementptr (%ptrs1* null, i32 0, i32 2) |
| 160 ; CHECK: @const_ptr = global [4 x i8] c"\08\00\00\00" |
| 161 |
| 162 @int_to_ptr = global i32* inttoptr (i16 260 to i32*) |
| 163 ; CHECK: @int_to_ptr = global [4 x i8] c"\04\01\00\00" |
| 164 |
| 165 ; Clang allows "(uintptr_t) &var" as a global initializer, so we |
| 166 ; handle this case. |
| 167 @ptr_to_int = global i32 ptrtoint (i8* @var2 to i32) |
| 168 ; CHECK: @ptr_to_int = global i32 ptrtoint ([1 x i8]* @var2 to i32) |
| 169 |
| 170 ; This is handled via Constant folding. The getelementptr is |
| 171 ; converted to an undef when it is created, so the pass does not see a |
| 172 ; getelementptr here. |
| 173 @undef_gep = global i32* getelementptr (%ptrs1* undef, i32 0, i32 2) |
| 174 ; CHECK: @undef_gep = global [4 x i8] zeroinitializer |
| 175 |
| 176 ; Adding an offset to a function address isn't useful, but check that |
| 177 ; the pass handles it anyway. |
| 178 @func_addend = global i8* getelementptr ( |
| 179 i8* bitcast (void ()* @func_with_block to i8*), i32 123) |
| 180 ; CHECK: @func_addend = global i32 add (i32 ptrtoint (void ()* @func_with_block
to i32), i32 123) |
| 181 |
| 182 ; Similarly, adding an offset to a label address isn't useful, but |
| 183 ; check it anyway. |
| 184 @block_addend = global i8* getelementptr ( |
| 185 i8* blockaddress(@func_with_block, %label), i32 100) |
| 186 ; CHECK: @block_addend = global i32 add (i32 ptrtoint (i8* blockaddress(@func_wi
th_block, %label) to i32), i32 100) |
| 187 |
| 188 |
| 189 ; Special cases |
| 190 |
| 191 ; Leave vars with "appending" linkage alone. |
| 192 @appending = appending global [1 x i32*] [i32* @var1] |
| 193 ; CHECK: @appending = appending global [1 x i32*] [i32* bitcast ([4 x i8]* @var1
to i32*)] |
| 194 |
| 195 |
| 196 define i32* @get_address() { |
| 197 ret i32* @var_i32 |
| 198 } |
| 199 ; CHECK: define i32* @get_address() { |
| 200 ; CHECK-NEXT: ret i32* bitcast ([4 x i8]* @var_i32 to i32*) |
| 201 |
| 202 |
| 203 define void @func_with_block() { |
| 204 br label %label |
| 205 label: |
| 206 ret void |
| 207 } |
OLD | NEW |