1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mattr=+cmov -mtriple=i386-pc-linux -verify-machineinstrs < %s | FileCheck %s -check-prefix=LINUX 3; RUN: llc -mattr=+cmov -mtriple=i386-macosx -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s -check-prefix=PIC 4 5@sc64 = external dso_local global i64 6 7define 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 $5, %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 $5, %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 62entry: 63 %max = atomicrmw max i64* @sc64, i64 5 acquire 64 ret i64 %max 65} 66 67define 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 116entry: 117 %min = atomicrmw min i64* @sc64, i64 6 acquire 118 ret i64 %min 119} 120 121define 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 176entry: 177 %umax = atomicrmw umax i64* @sc64, i64 7 acquire 178 ret i64 %umax 179} 180 181define 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 230entry: 231 %umin = atomicrmw umin i64* @sc64, i64 8 acquire 232 ret i64 %umin 233} 234 235@id = internal global i64 0, align 8 236 237define 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 294entry: 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