347 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s --check-prefix=CHECK --check-prefix=FASTINCDEC3; RUN: llc < %s -mtriple=x86_64-- -mattr=slow-incdec | FileCheck %s --check-prefix=CHECK --check-prefix=SLOWINCDEC4 5define i32 @test_add_1_cmov_slt(ptr %p, i32 %a0, i32 %a1) #0 {6; FASTINCDEC-LABEL: test_add_1_cmov_slt:7; FASTINCDEC: # %bb.0: # %entry8; FASTINCDEC-NEXT: movl %esi, %eax9; FASTINCDEC-NEXT: lock incq (%rdi)10; FASTINCDEC-NEXT: cmovgl %edx, %eax11; FASTINCDEC-NEXT: retq12;13; SLOWINCDEC-LABEL: test_add_1_cmov_slt:14; SLOWINCDEC: # %bb.0: # %entry15; SLOWINCDEC-NEXT: movl %esi, %eax16; SLOWINCDEC-NEXT: lock addq $1, (%rdi)17; SLOWINCDEC-NEXT: cmovgl %edx, %eax18; SLOWINCDEC-NEXT: retq19entry:20 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst21 %tmp1 = icmp slt i64 %tmp0, 022 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a123 ret i32 %tmp224}25 26define i32 @test_add_1_cmov_sge(ptr %p, i32 %a0, i32 %a1) #0 {27; FASTINCDEC-LABEL: test_add_1_cmov_sge:28; FASTINCDEC: # %bb.0: # %entry29; FASTINCDEC-NEXT: movl %esi, %eax30; FASTINCDEC-NEXT: lock incq (%rdi)31; FASTINCDEC-NEXT: cmovlel %edx, %eax32; FASTINCDEC-NEXT: retq33;34; SLOWINCDEC-LABEL: test_add_1_cmov_sge:35; SLOWINCDEC: # %bb.0: # %entry36; SLOWINCDEC-NEXT: movl %esi, %eax37; SLOWINCDEC-NEXT: lock addq $1, (%rdi)38; SLOWINCDEC-NEXT: cmovlel %edx, %eax39; SLOWINCDEC-NEXT: retq40entry:41 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst42 %tmp1 = icmp sge i64 %tmp0, 043 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a144 ret i32 %tmp245}46 47define i32 @test_sub_1_cmov_sle(ptr %p, i32 %a0, i32 %a1) #0 {48; FASTINCDEC-LABEL: test_sub_1_cmov_sle:49; FASTINCDEC: # %bb.0: # %entry50; FASTINCDEC-NEXT: movl %esi, %eax51; FASTINCDEC-NEXT: lock decq (%rdi)52; FASTINCDEC-NEXT: cmovgel %edx, %eax53; FASTINCDEC-NEXT: retq54;55; SLOWINCDEC-LABEL: test_sub_1_cmov_sle:56; SLOWINCDEC: # %bb.0: # %entry57; SLOWINCDEC-NEXT: movl %esi, %eax58; SLOWINCDEC-NEXT: lock subq $1, (%rdi)59; SLOWINCDEC-NEXT: cmovgel %edx, %eax60; SLOWINCDEC-NEXT: retq61entry:62 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst63 %tmp1 = icmp sle i64 %tmp0, 064 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a165 ret i32 %tmp266}67 68define i32 @test_sub_1_cmov_sgt(ptr %p, i32 %a0, i32 %a1) #0 {69; FASTINCDEC-LABEL: test_sub_1_cmov_sgt:70; FASTINCDEC: # %bb.0: # %entry71; FASTINCDEC-NEXT: movl %esi, %eax72; FASTINCDEC-NEXT: lock decq (%rdi)73; FASTINCDEC-NEXT: cmovll %edx, %eax74; FASTINCDEC-NEXT: retq75;76; SLOWINCDEC-LABEL: test_sub_1_cmov_sgt:77; SLOWINCDEC: # %bb.0: # %entry78; SLOWINCDEC-NEXT: movl %esi, %eax79; SLOWINCDEC-NEXT: lock addq $-1, (%rdi)80; SLOWINCDEC-NEXT: cmovll %edx, %eax81; SLOWINCDEC-NEXT: retq82entry:83 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst84 %tmp1 = icmp sgt i64 %tmp0, 085 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a186 ret i32 %tmp287}88 89; FIXME: (setcc slt x, 0) gets combined into shr early.90define i8 @test_add_1_setcc_slt(ptr %p) #0 {91; CHECK-LABEL: test_add_1_setcc_slt:92; CHECK: # %bb.0: # %entry93; CHECK-NEXT: movl $1, %eax94; CHECK-NEXT: lock xaddq %rax, (%rdi)95; CHECK-NEXT: shrq $63, %rax96; CHECK-NEXT: # kill: def $al killed $al killed $rax97; CHECK-NEXT: retq98entry:99 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst100 %tmp1 = icmp slt i64 %tmp0, 0101 %tmp2 = zext i1 %tmp1 to i8102 ret i8 %tmp2103}104 105define i8 @test_sub_1_setcc_sgt(ptr %p) #0 {106; FASTINCDEC-LABEL: test_sub_1_setcc_sgt:107; FASTINCDEC: # %bb.0: # %entry108; FASTINCDEC-NEXT: lock decq (%rdi)109; FASTINCDEC-NEXT: setge %al110; FASTINCDEC-NEXT: retq111;112; SLOWINCDEC-LABEL: test_sub_1_setcc_sgt:113; SLOWINCDEC: # %bb.0: # %entry114; SLOWINCDEC-NEXT: lock addq $-1, (%rdi)115; SLOWINCDEC-NEXT: setge %al116; SLOWINCDEC-NEXT: retq117entry:118 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst119 %tmp1 = icmp sgt i64 %tmp0, 0120 %tmp2 = zext i1 %tmp1 to i8121 ret i8 %tmp2122}123 124define i32 @test_add_1_brcond_sge(ptr %p, i32 %a0, i32 %a1) #0 {125; FASTINCDEC-LABEL: test_add_1_brcond_sge:126; FASTINCDEC: # %bb.0: # %entry127; FASTINCDEC-NEXT: lock incq (%rdi)128; FASTINCDEC-NEXT: jle .LBB6_2129; FASTINCDEC-NEXT: # %bb.1: # %t130; FASTINCDEC-NEXT: movl %esi, %eax131; FASTINCDEC-NEXT: retq132; FASTINCDEC-NEXT: .LBB6_2: # %f133; FASTINCDEC-NEXT: movl %edx, %eax134; FASTINCDEC-NEXT: retq135;136; SLOWINCDEC-LABEL: test_add_1_brcond_sge:137; SLOWINCDEC: # %bb.0: # %entry138; SLOWINCDEC-NEXT: lock addq $1, (%rdi)139; SLOWINCDEC-NEXT: jle .LBB6_2140; SLOWINCDEC-NEXT: # %bb.1: # %t141; SLOWINCDEC-NEXT: movl %esi, %eax142; SLOWINCDEC-NEXT: retq143; SLOWINCDEC-NEXT: .LBB6_2: # %f144; SLOWINCDEC-NEXT: movl %edx, %eax145; SLOWINCDEC-NEXT: retq146entry:147 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst148 %tmp1 = icmp sge i64 %tmp0, 0149 br i1 %tmp1, label %t, label %f150t:151 ret i32 %a0152f:153 ret i32 %a1154}155 156; Also make sure we don't muck with condition codes that we should ignore.157; No need to test unsigned comparisons, as they should all be simplified.158 159define i32 @test_add_1_cmov_sle(ptr %p, i32 %a0, i32 %a1) #0 {160; CHECK-LABEL: test_add_1_cmov_sle:161; CHECK: # %bb.0: # %entry162; CHECK-NEXT: movl %esi, %eax163; CHECK-NEXT: movl $1, %ecx164; CHECK-NEXT: lock xaddq %rcx, (%rdi)165; CHECK-NEXT: testq %rcx, %rcx166; CHECK-NEXT: cmovgl %edx, %eax167; CHECK-NEXT: retq168entry:169 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst170 %tmp1 = icmp sle i64 %tmp0, 0171 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1172 ret i32 %tmp2173}174 175define i32 @test_add_1_cmov_sgt(ptr %p, i32 %a0, i32 %a1) #0 {176; CHECK-LABEL: test_add_1_cmov_sgt:177; CHECK: # %bb.0: # %entry178; CHECK-NEXT: movl %esi, %eax179; CHECK-NEXT: movl $1, %ecx180; CHECK-NEXT: lock xaddq %rcx, (%rdi)181; CHECK-NEXT: testq %rcx, %rcx182; CHECK-NEXT: cmovlel %edx, %eax183; CHECK-NEXT: retq184entry:185 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst186 %tmp1 = icmp sgt i64 %tmp0, 0187 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1188 ret i32 %tmp2189}190 191; Test a result being used by more than just the comparison.192 193define i8 @test_add_1_setcc_sgt_reuse(ptr %p, ptr %p2) #0 {194; CHECK-LABEL: test_add_1_setcc_sgt_reuse:195; CHECK: # %bb.0: # %entry196; CHECK-NEXT: movl $1, %ecx197; CHECK-NEXT: lock xaddq %rcx, (%rdi)198; CHECK-NEXT: testq %rcx, %rcx199; CHECK-NEXT: setg %al200; CHECK-NEXT: movq %rcx, (%rsi)201; CHECK-NEXT: retq202entry:203 %tmp0 = atomicrmw add ptr %p, i64 1 seq_cst204 %tmp1 = icmp sgt i64 %tmp0, 0205 %tmp2 = zext i1 %tmp1 to i8206 store i64 %tmp0, ptr %p2207 ret i8 %tmp2208}209 210define i8 @test_sub_2_setcc_sgt(ptr %p) #0 {211; CHECK-LABEL: test_sub_2_setcc_sgt:212; CHECK: # %bb.0: # %entry213; CHECK-NEXT: movq $-2, %rax214; CHECK-NEXT: lock xaddq %rax, (%rdi)215; CHECK-NEXT: testq %rax, %rax216; CHECK-NEXT: setg %al217; CHECK-NEXT: retq218entry:219 %tmp0 = atomicrmw sub ptr %p, i64 2 seq_cst220 %tmp1 = icmp sgt i64 %tmp0, 0221 %tmp2 = zext i1 %tmp1 to i8222 ret i8 %tmp2223}224 225; TODO: It's possible to use "lock inc" here, but both cmovs need to be updated.226define i8 @test_add_1_cmov_cmov(ptr %p, ptr %q) #0 {227; CHECK-LABEL: test_add_1_cmov_cmov:228; CHECK: # %bb.0: # %entry229; CHECK-NEXT: movl $1, %eax230; CHECK-NEXT: lock xaddq %rax, (%rdi)231; CHECK-NEXT: testq %rax, %rax232; CHECK-NEXT: movl $12, %eax233; CHECK-NEXT: movl $34, %ecx234; CHECK-NEXT: cmovsl %eax, %ecx235; CHECK-NEXT: movb %cl, (%rsi)236; CHECK-NEXT: movl $56, %ecx237; CHECK-NEXT: movl $78, %eax238; CHECK-NEXT: cmovsl %ecx, %eax239; CHECK-NEXT: # kill: def $al killed $al killed $eax240; CHECK-NEXT: retq241entry:242 %add = atomicrmw add ptr %p, i64 1 seq_cst243 %cmp = icmp slt i64 %add, 0244 %s1 = select i1 %cmp, i8 12, i8 34245 store i8 %s1, ptr %q246 %s2 = select i1 %cmp, i8 56, i8 78247 ret i8 %s2248}249 250define i8 @test_sub_1_cmp_1_setcc_eq(ptr %p) #0 {251; FASTINCDEC-LABEL: test_sub_1_cmp_1_setcc_eq:252; FASTINCDEC: # %bb.0: # %entry253; FASTINCDEC-NEXT: lock decq (%rdi)254; FASTINCDEC-NEXT: sete %al255; FASTINCDEC-NEXT: retq256;257; SLOWINCDEC-LABEL: test_sub_1_cmp_1_setcc_eq:258; SLOWINCDEC: # %bb.0: # %entry259; SLOWINCDEC-NEXT: lock subq $1, (%rdi)260; SLOWINCDEC-NEXT: sete %al261; SLOWINCDEC-NEXT: retq262entry:263 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst264 %tmp1 = icmp eq i64 %tmp0, 1265 %tmp2 = zext i1 %tmp1 to i8266 ret i8 %tmp2267}268 269define i8 @test_sub_1_cmp_1_setcc_ne(ptr %p) #0 {270; FASTINCDEC-LABEL: test_sub_1_cmp_1_setcc_ne:271; FASTINCDEC: # %bb.0: # %entry272; FASTINCDEC-NEXT: lock decq (%rdi)273; FASTINCDEC-NEXT: setne %al274; FASTINCDEC-NEXT: retq275;276; SLOWINCDEC-LABEL: test_sub_1_cmp_1_setcc_ne:277; SLOWINCDEC: # %bb.0: # %entry278; SLOWINCDEC-NEXT: lock subq $1, (%rdi)279; SLOWINCDEC-NEXT: setne %al280; SLOWINCDEC-NEXT: retq281entry:282 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst283 %tmp1 = icmp ne i64 %tmp0, 1284 %tmp2 = zext i1 %tmp1 to i8285 ret i8 %tmp2286}287 288define i8 @test_sub_1_cmp_1_setcc_ugt(ptr %p) #0 {289; CHECK-LABEL: test_sub_1_cmp_1_setcc_ugt:290; CHECK: # %bb.0: # %entry291; CHECK-NEXT: lock subq $1, (%rdi)292; CHECK-NEXT: seta %al293; CHECK-NEXT: retq294entry:295 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst296 %tmp1 = icmp ugt i64 %tmp0, 1297 %tmp2 = zext i1 %tmp1 to i8298 ret i8 %tmp2299}300 301define i8 @test_sub_1_cmp_1_setcc_sle(ptr %p) #0 {302; FASTINCDEC-LABEL: test_sub_1_cmp_1_setcc_sle:303; FASTINCDEC: # %bb.0: # %entry304; FASTINCDEC-NEXT: lock decq (%rdi)305; FASTINCDEC-NEXT: setle %al306; FASTINCDEC-NEXT: retq307;308; SLOWINCDEC-LABEL: test_sub_1_cmp_1_setcc_sle:309; SLOWINCDEC: # %bb.0: # %entry310; SLOWINCDEC-NEXT: lock subq $1, (%rdi)311; SLOWINCDEC-NEXT: setle %al312; SLOWINCDEC-NEXT: retq313entry:314 %tmp0 = atomicrmw sub ptr %p, i64 1 seq_cst315 %tmp1 = icmp sle i64 %tmp0, 1316 %tmp2 = zext i1 %tmp1 to i8317 ret i8 %tmp2318}319 320define i8 @test_sub_3_cmp_3_setcc_eq(ptr %p) #0 {321; CHECK-LABEL: test_sub_3_cmp_3_setcc_eq:322; CHECK: # %bb.0: # %entry323; CHECK-NEXT: lock subq $3, (%rdi)324; CHECK-NEXT: sete %al325; CHECK-NEXT: retq326entry:327 %tmp0 = atomicrmw sub ptr %p, i64 3 seq_cst328 %tmp1 = icmp eq i64 %tmp0, 3329 %tmp2 = zext i1 %tmp1 to i8330 ret i8 %tmp2331}332 333define i8 @test_sub_3_cmp_3_setcc_uge(ptr %p) #0 {334; CHECK-LABEL: test_sub_3_cmp_3_setcc_uge:335; CHECK: # %bb.0: # %entry336; CHECK-NEXT: lock subq $3, (%rdi)337; CHECK-NEXT: setae %al338; CHECK-NEXT: retq339entry:340 %tmp0 = atomicrmw sub ptr %p, i64 3 seq_cst341 %tmp1 = icmp uge i64 %tmp0, 3342 %tmp2 = zext i1 %tmp1 to i8343 ret i8 %tmp2344}345 346attributes #0 = { nounwind }347