1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc -mattr=+cmov,cx16 -mtriple=i386-pc-linux -verify-machineinstrs < %s | FileCheck %s -check-prefix=LINUX 3 ; RUN: llc -mattr=cx16 -mtriple=i386-macosx -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s -check-prefix=PIC 4 5 @sc64 = external global i64 6 7 define i64 @atomic_max_i64() nounwind { 8 ; LINUX-LABEL: atomic_max_i64: 9 ; LINUX: # %bb.0: # %entry 10 ; LINUX-NEXT: pushl %ebx 11 ; LINUX-NEXT: pushl %esi 12 ; LINUX-NEXT: movl sc64+4, %edx 13 ; LINUX-NEXT: movl sc64, %eax 14 ; LINUX-NEXT: movl $4, %esi 15 ; LINUX-NEXT: .p2align 4, 0x90 16 ; LINUX-NEXT: .LBB0_1: # %atomicrmw.start 17 ; LINUX-NEXT: # =>This Inner Loop Header: Depth=1 18 ; LINUX-NEXT: cmpl %eax, %esi 19 ; LINUX-NEXT: movl $0, %ecx 20 ; LINUX-NEXT: sbbl %edx, %ecx 21 ; LINUX-NEXT: movl $0, %ecx 22 ; LINUX-NEXT: cmovll %edx, %ecx 23 ; LINUX-NEXT: movl $5, %ebx 24 ; LINUX-NEXT: cmovll %eax, %ebx 25 ; LINUX-NEXT: lock cmpxchg8b sc64 26 ; LINUX-NEXT: jne .LBB0_1 27 ; LINUX-NEXT: # %bb.2: # %atomicrmw.end 28 ; LINUX-NEXT: popl %esi 29 ; LINUX-NEXT: popl %ebx 30 ; LINUX-NEXT: retl 31 ; 32 ; PIC-LABEL: atomic_max_i64: 33 ; PIC: ## %bb.0: ## %entry 34 ; PIC-NEXT: pushl %ebx 35 ; PIC-NEXT: pushl %edi 36 ; PIC-NEXT: pushl %esi 37 ; PIC-NEXT: calll L0$pb 38 ; PIC-NEXT: L0$pb: 39 ; PIC-NEXT: popl %eax 40 ; PIC-NEXT: movl L_sc64$non_lazy_ptr-L0$pb(%eax), %esi 41 ; PIC-NEXT: movl (%esi), %eax 42 ; PIC-NEXT: movl 4(%esi), %edx 43 ; PIC-NEXT: movl $4, %edi 44 ; PIC-NEXT: .p2align 4, 0x90 45 ; PIC-NEXT: LBB0_1: ## %atomicrmw.start 46 ; PIC-NEXT: ## =>This Inner Loop Header: Depth=1 47 ; PIC-NEXT: cmpl %eax, %edi 48 ; PIC-NEXT: movl $0, %ecx 49 ; PIC-NEXT: sbbl %edx, %ecx 50 ; PIC-NEXT: movl $0, %ecx 51 ; PIC-NEXT: cmovll %edx, %ecx 52 ; PIC-NEXT: movl $5, %ebx 53 ; PIC-NEXT: cmovll %eax, %ebx 54 ; PIC-NEXT: lock cmpxchg8b (%esi) 55 ; PIC-NEXT: jne LBB0_1 56 ; PIC-NEXT: ## %bb.2: ## %atomicrmw.end 57 ; PIC-NEXT: popl %esi 58 ; PIC-NEXT: popl %edi 59 ; PIC-NEXT: popl %ebx 60 ; PIC-NEXT: retl 61 ; PIC-NEXT: ## -- End function 62 entry: 63 %max = atomicrmw max i64* @sc64, i64 5 acquire 64 ret i64 %max 65 } 66 67 define i64 @atomic_min_i64() nounwind { 68 ; LINUX-LABEL: atomic_min_i64: 69 ; LINUX: # %bb.0: # %entry 70 ; LINUX-NEXT: pushl %ebx 71 ; LINUX-NEXT: movl sc64+4, %edx 72 ; LINUX-NEXT: movl sc64, %eax 73 ; LINUX-NEXT: .p2align 4, 0x90 74 ; LINUX-NEXT: .LBB1_1: # %atomicrmw.start 75 ; LINUX-NEXT: # =>This Inner Loop Header: Depth=1 76 ; LINUX-NEXT: cmpl $7, %eax 77 ; LINUX-NEXT: movl %edx, %ecx 78 ; LINUX-NEXT: sbbl $0, %ecx 79 ; LINUX-NEXT: movl $0, %ecx 80 ; LINUX-NEXT: cmovll %edx, %ecx 81 ; LINUX-NEXT: movl $6, %ebx 82 ; LINUX-NEXT: cmovll %eax, %ebx 83 ; LINUX-NEXT: lock cmpxchg8b sc64 84 ; LINUX-NEXT: jne .LBB1_1 85 ; LINUX-NEXT: # %bb.2: # %atomicrmw.end 86 ; LINUX-NEXT: popl %ebx 87 ; LINUX-NEXT: retl 88 ; 89 ; PIC-LABEL: atomic_min_i64: 90 ; PIC: ## %bb.0: ## %entry 91 ; PIC-NEXT: pushl %ebx 92 ; PIC-NEXT: pushl %esi 93 ; PIC-NEXT: calll L1$pb 94 ; PIC-NEXT: L1$pb: 95 ; PIC-NEXT: popl %eax 96 ; PIC-NEXT: movl L_sc64$non_lazy_ptr-L1$pb(%eax), %esi 97 ; PIC-NEXT: movl (%esi), %eax 98 ; PIC-NEXT: movl 4(%esi), %edx 99 ; PIC-NEXT: .p2align 4, 0x90 100 ; PIC-NEXT: LBB1_1: ## %atomicrmw.start 101 ; PIC-NEXT: ## =>This Inner Loop Header: Depth=1 102 ; PIC-NEXT: cmpl $7, %eax 103 ; PIC-NEXT: movl %edx, %ecx 104 ; PIC-NEXT: sbbl $0, %ecx 105 ; PIC-NEXT: movl $0, %ecx 106 ; PIC-NEXT: cmovll %edx, %ecx 107 ; PIC-NEXT: movl $6, %ebx 108 ; PIC-NEXT: cmovll %eax, %ebx 109 ; PIC-NEXT: lock cmpxchg8b (%esi) 110 ; PIC-NEXT: jne LBB1_1 111 ; PIC-NEXT: ## %bb.2: ## %atomicrmw.end 112 ; PIC-NEXT: popl %esi 113 ; PIC-NEXT: popl %ebx 114 ; PIC-NEXT: retl 115 ; PIC-NEXT: ## -- End function 116 entry: 117 %min = atomicrmw min i64* @sc64, i64 6 acquire 118 ret i64 %min 119 } 120 121 define i64 @atomic_umax_i64() nounwind { 122 ; LINUX-LABEL: atomic_umax_i64: 123 ; LINUX: # %bb.0: # %entry 124 ; LINUX-NEXT: pushl %ebx 125 ; LINUX-NEXT: pushl %esi 126 ; LINUX-NEXT: movl sc64+4, %edx 127 ; LINUX-NEXT: movl sc64, %eax 128 ; LINUX-NEXT: movl $7, %esi 129 ; LINUX-NEXT: .p2align 4, 0x90 130 ; LINUX-NEXT: .LBB2_1: # %atomicrmw.start 131 ; LINUX-NEXT: # =>This Inner Loop Header: Depth=1 132 ; LINUX-NEXT: cmpl %eax, %esi 133 ; LINUX-NEXT: movl $0, %ecx 134 ; LINUX-NEXT: sbbl %edx, %ecx 135 ; LINUX-NEXT: movl $0, %ecx 136 ; LINUX-NEXT: cmovbl %edx, %ecx 137 ; LINUX-NEXT: movl $7, %ebx 138 ; LINUX-NEXT: cmovbl %eax, %ebx 139 ; LINUX-NEXT: lock cmpxchg8b sc64 140 ; LINUX-NEXT: jne .LBB2_1 141 ; LINUX-NEXT: # %bb.2: # %atomicrmw.end 142 ; LINUX-NEXT: popl %esi 143 ; LINUX-NEXT: popl %ebx 144 ; LINUX-NEXT: retl 145 ; 146 ; PIC-LABEL: atomic_umax_i64: 147 ; PIC: ## %bb.0: ## %entry 148 ; PIC-NEXT: pushl %ebx 149 ; PIC-NEXT: pushl %edi 150 ; PIC-NEXT: pushl %esi 151 ; PIC-NEXT: calll L2$pb 152 ; PIC-NEXT: L2$pb: 153 ; PIC-NEXT: popl %eax 154 ; PIC-NEXT: movl L_sc64$non_lazy_ptr-L2$pb(%eax), %esi 155 ; PIC-NEXT: movl (%esi), %eax 156 ; PIC-NEXT: movl 4(%esi), %edx 157 ; PIC-NEXT: movl $7, %edi 158 ; PIC-NEXT: .p2align 4, 0x90 159 ; PIC-NEXT: LBB2_1: ## %atomicrmw.start 160 ; PIC-NEXT: ## =>This Inner Loop Header: Depth=1 161 ; PIC-NEXT: cmpl %eax, %edi 162 ; PIC-NEXT: movl $0, %ecx 163 ; PIC-NEXT: sbbl %edx, %ecx 164 ; PIC-NEXT: movl $0, %ecx 165 ; PIC-NEXT: cmovbl %edx, %ecx 166 ; PIC-NEXT: movl $7, %ebx 167 ; PIC-NEXT: cmovbl %eax, %ebx 168 ; PIC-NEXT: lock cmpxchg8b (%esi) 169 ; PIC-NEXT: jne LBB2_1 170 ; PIC-NEXT: ## %bb.2: ## %atomicrmw.end 171 ; PIC-NEXT: popl %esi 172 ; PIC-NEXT: popl %edi 173 ; PIC-NEXT: popl %ebx 174 ; PIC-NEXT: retl 175 ; PIC-NEXT: ## -- End function 176 entry: 177 %umax = atomicrmw umax i64* @sc64, i64 7 acquire 178 ret i64 %umax 179 } 180 181 define i64 @atomic_umin_i64() nounwind { 182 ; LINUX-LABEL: atomic_umin_i64: 183 ; LINUX: # %bb.0: # %entry 184 ; LINUX-NEXT: pushl %ebx 185 ; LINUX-NEXT: movl sc64+4, %edx 186 ; LINUX-NEXT: movl sc64, %eax 187 ; LINUX-NEXT: .p2align 4, 0x90 188 ; LINUX-NEXT: .LBB3_1: # %atomicrmw.start 189 ; LINUX-NEXT: # =>This Inner Loop Header: Depth=1 190 ; LINUX-NEXT: cmpl $9, %eax 191 ; LINUX-NEXT: movl %edx, %ecx 192 ; LINUX-NEXT: sbbl $0, %ecx 193 ; LINUX-NEXT: movl $0, %ecx 194 ; LINUX-NEXT: cmovbl %edx, %ecx 195 ; LINUX-NEXT: movl $8, %ebx 196 ; LINUX-NEXT: cmovbl %eax, %ebx 197 ; LINUX-NEXT: lock cmpxchg8b sc64 198 ; LINUX-NEXT: jne .LBB3_1 199 ; LINUX-NEXT: # %bb.2: # %atomicrmw.end 200 ; LINUX-NEXT: popl %ebx 201 ; LINUX-NEXT: retl 202 ; 203 ; PIC-LABEL: atomic_umin_i64: 204 ; PIC: ## %bb.0: ## %entry 205 ; PIC-NEXT: pushl %ebx 206 ; PIC-NEXT: pushl %esi 207 ; PIC-NEXT: calll L3$pb 208 ; PIC-NEXT: L3$pb: 209 ; PIC-NEXT: popl %eax 210 ; PIC-NEXT: movl L_sc64$non_lazy_ptr-L3$pb(%eax), %esi 211 ; PIC-NEXT: movl (%esi), %eax 212 ; PIC-NEXT: movl 4(%esi), %edx 213 ; PIC-NEXT: .p2align 4, 0x90 214 ; PIC-NEXT: LBB3_1: ## %atomicrmw.start 215 ; PIC-NEXT: ## =>This Inner Loop Header: Depth=1 216 ; PIC-NEXT: cmpl $9, %eax 217 ; PIC-NEXT: movl %edx, %ecx 218 ; PIC-NEXT: sbbl $0, %ecx 219 ; PIC-NEXT: movl $0, %ecx 220 ; PIC-NEXT: cmovbl %edx, %ecx 221 ; PIC-NEXT: movl $8, %ebx 222 ; PIC-NEXT: cmovbl %eax, %ebx 223 ; PIC-NEXT: lock cmpxchg8b (%esi) 224 ; PIC-NEXT: jne LBB3_1 225 ; PIC-NEXT: ## %bb.2: ## %atomicrmw.end 226 ; PIC-NEXT: popl %esi 227 ; PIC-NEXT: popl %ebx 228 ; PIC-NEXT: retl 229 ; PIC-NEXT: ## -- End function 230 entry: 231 %umin = atomicrmw umin i64* @sc64, i64 8 acquire 232 ret i64 %umin 233 } 234 235 @id = internal global i64 0, align 8 236 237 define void @tf_bug(i8* %ptr) nounwind { 238 ; LINUX-LABEL: tf_bug: 239 ; LINUX: # %bb.0: # %entry 240 ; LINUX-NEXT: pushl %ebx 241 ; LINUX-NEXT: pushl %esi 242 ; LINUX-NEXT: movl {{[0-9]+}}(%esp), %esi 243 ; LINUX-NEXT: movl id+4, %edx 244 ; LINUX-NEXT: movl id, %eax 245 ; LINUX-NEXT: .p2align 4, 0x90 246 ; LINUX-NEXT: .LBB4_1: # %atomicrmw.start 247 ; LINUX-NEXT: # =>This Inner Loop Header: Depth=1 248 ; LINUX-NEXT: movl %eax, %ebx 249 ; LINUX-NEXT: addl $1, %ebx 250 ; LINUX-NEXT: movl %edx, %ecx 251 ; LINUX-NEXT: adcl $0, %ecx 252 ; LINUX-NEXT: lock cmpxchg8b id 253 ; LINUX-NEXT: jne .LBB4_1 254 ; LINUX-NEXT: # %bb.2: # %atomicrmw.end 255 ; LINUX-NEXT: addl $1, %eax 256 ; LINUX-NEXT: adcl $0, %edx 257 ; LINUX-NEXT: movl %eax, (%esi) 258 ; LINUX-NEXT: movl %edx, 4(%esi) 259 ; LINUX-NEXT: popl %esi 260 ; LINUX-NEXT: popl %ebx 261 ; LINUX-NEXT: retl 262 ; 263 ; PIC-LABEL: tf_bug: 264 ; PIC: ## %bb.0: ## %entry 265 ; PIC-NEXT: pushl %ebx 266 ; PIC-NEXT: pushl %edi 267 ; PIC-NEXT: pushl %esi 268 ; PIC-NEXT: calll L4$pb 269 ; PIC-NEXT: L4$pb: 270 ; PIC-NEXT: popl %edi 271 ; PIC-NEXT: movl {{[0-9]+}}(%esp), %esi 272 ; PIC-NEXT: movl (_id-L4$pb)+4(%edi), %edx 273 ; PIC-NEXT: movl _id-L4$pb(%edi), %eax 274 ; PIC-NEXT: .p2align 4, 0x90 275 ; PIC-NEXT: LBB4_1: ## %atomicrmw.start 276 ; PIC-NEXT: ## =>This Inner Loop Header: Depth=1 277 ; PIC-NEXT: movl %eax, %ebx 278 ; PIC-NEXT: addl $1, %ebx 279 ; PIC-NEXT: movl %edx, %ecx 280 ; PIC-NEXT: adcl $0, %ecx 281 ; PIC-NEXT: lock cmpxchg8b _id-L4$pb(%edi) 282 ; PIC-NEXT: jne LBB4_1 283 ; PIC-NEXT: ## %bb.2: ## %atomicrmw.end 284 ; PIC-NEXT: addl $1, %eax 285 ; PIC-NEXT: adcl $0, %edx 286 ; PIC-NEXT: movl %eax, (%esi) 287 ; PIC-NEXT: movl %edx, 4(%esi) 288 ; PIC-NEXT: popl %esi 289 ; PIC-NEXT: popl %edi 290 ; PIC-NEXT: popl %ebx 291 ; PIC-NEXT: retl 292 ; PIC-NEXT: ## -- End function 293 ; PIC-NEXT: .zerofill __DATA,__bss,_id,8,3 ## @id 294 entry: 295 %tmp1 = atomicrmw add i64* @id, i64 1 seq_cst 296 %tmp2 = add i64 %tmp1, 1 297 %tmp3 = bitcast i8* %ptr to i64* 298 store i64 %tmp2, i64* %tmp3, align 4 299 ret void 300 } 301