1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i386-unknown-linux-gnu -mattr=-slow-incdec < %s | FileCheck -check-prefix=CHECK -check-prefix=INCDEC %s 3; RUN: llc -mtriple=i386-unknown-linux-gnu -mattr=+slow-incdec < %s | FileCheck -check-prefix=CHECK -check-prefix=ADD %s 4 5define i32 @inc(i32 %x) { 6; INCDEC-LABEL: inc: 7; INCDEC: # %bb.0: 8; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax 9; INCDEC-NEXT: incl %eax 10; INCDEC-NEXT: retl 11; 12; ADD-LABEL: inc: 13; ADD: # %bb.0: 14; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax 15; ADD-NEXT: addl $1, %eax 16; ADD-NEXT: retl 17 %r = add i32 %x, 1 18 ret i32 %r 19} 20 21define i32 @dec(i32 %x) { 22; INCDEC-LABEL: dec: 23; INCDEC: # %bb.0: 24; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax 25; INCDEC-NEXT: decl %eax 26; INCDEC-NEXT: retl 27; 28; ADD-LABEL: dec: 29; ADD: # %bb.0: 30; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax 31; ADD-NEXT: addl $-1, %eax 32; ADD-NEXT: retl 33 %r = add i32 %x, -1 34 ret i32 %r 35} 36 37define i32 @inc_size(i32 %x) optsize { 38; CHECK-LABEL: inc_size: 39; CHECK: # %bb.0: 40; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 41; CHECK-NEXT: incl %eax 42; CHECK-NEXT: retl 43 %r = add i32 %x, 1 44 ret i32 %r 45} 46 47define i32 @dec_size(i32 %x) optsize { 48; CHECK-LABEL: dec_size: 49; CHECK: # %bb.0: 50; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 51; CHECK-NEXT: decl %eax 52; CHECK-NEXT: retl 53 %r = add i32 %x, -1 54 ret i32 %r 55} 56 57define i32 @inc_pgso(i32 %x) !prof !14 { 58; CHECK-LABEL: inc_pgso: 59; CHECK: # %bb.0: 60; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 61; CHECK-NEXT: incl %eax 62; CHECK-NEXT: retl 63 %r = add i32 %x, 1 64 ret i32 %r 65} 66 67define i32 @dec_pgso(i32 %x) !prof !14 { 68; CHECK-LABEL: dec_pgso: 69; CHECK: # %bb.0: 70; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 71; CHECK-NEXT: decl %eax 72; CHECK-NEXT: retl 73 %r = add i32 %x, -1 74 ret i32 %r 75} 76 77declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) 78declare void @other(i32* ) nounwind; 79 80define void @cond_ae_to_cond_ne(i32* %p) nounwind { 81; INCDEC-LABEL: cond_ae_to_cond_ne: 82; INCDEC: # %bb.0: # %entry 83; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax 84; INCDEC-NEXT: incl (%eax) 85; INCDEC-NEXT: jne .LBB6_1 86; INCDEC-NEXT: # %bb.2: # %if.end4 87; INCDEC-NEXT: jmp other@PLT # TAILCALL 88; INCDEC-NEXT: .LBB6_1: # %return 89; INCDEC-NEXT: retl 90; 91; ADD-LABEL: cond_ae_to_cond_ne: 92; ADD: # %bb.0: # %entry 93; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax 94; ADD-NEXT: addl $1, (%eax) 95; ADD-NEXT: jne .LBB6_1 96; ADD-NEXT: # %bb.2: # %if.end4 97; ADD-NEXT: jmp other@PLT # TAILCALL 98; ADD-NEXT: .LBB6_1: # %return 99; ADD-NEXT: retl 100entry: 101 %t0 = load i32, i32* %p, align 8 102 %add_ov = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %t0, i32 1) 103 %inc = extractvalue { i32, i1 } %add_ov, 0 104 store i32 %inc, i32* %p, align 8 105 %ov = extractvalue { i32, i1 } %add_ov, 1 106 br i1 %ov, label %if.end4, label %return 107 108if.end4: 109 tail call void @other(i32* %p) nounwind 110 br label %return 111 112return: 113 ret void 114} 115 116@a = common global i8 0, align 1 117@d = common global i8 0, align 1 118 119declare void @external_a() 120declare void @external_b() 121declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) 122 123define void @test_tail_call(i32* %ptr) nounwind { 124; INCDEC-LABEL: test_tail_call: 125; INCDEC: # %bb.0: # %entry 126; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax 127; INCDEC-NEXT: incl (%eax) 128; INCDEC-NEXT: setne %al 129; INCDEC-NEXT: incb a 130; INCDEC-NEXT: sete d 131; INCDEC-NEXT: testb %al, %al 132; INCDEC-NEXT: jne .LBB7_2 133; INCDEC-NEXT: # %bb.1: # %then 134; INCDEC-NEXT: jmp external_a@PLT # TAILCALL 135; INCDEC-NEXT: .LBB7_2: # %else 136; INCDEC-NEXT: jmp external_b@PLT # TAILCALL 137; 138; ADD-LABEL: test_tail_call: 139; ADD: # %bb.0: # %entry 140; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax 141; ADD-NEXT: addl $1, (%eax) 142; ADD-NEXT: setne %al 143; ADD-NEXT: addb $1, a 144; ADD-NEXT: sete d 145; ADD-NEXT: testb %al, %al 146; ADD-NEXT: jne .LBB7_2 147; ADD-NEXT: # %bb.1: # %then 148; ADD-NEXT: jmp external_a@PLT # TAILCALL 149; ADD-NEXT: .LBB7_2: # %else 150; ADD-NEXT: jmp external_b@PLT # TAILCALL 151entry: 152 %val = load i32, i32* %ptr 153 %add_ov = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val, i32 1) 154 %inc = extractvalue { i32, i1 } %add_ov, 0 155 store i32 %inc, i32* %ptr 156 %cmp = extractvalue { i32, i1 } %add_ov, 1 157 %aval = load volatile i8, i8* @a 158 %add_ov2 = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %aval, i8 1) 159 %inc2 = extractvalue { i8, i1 } %add_ov2, 0 160 store volatile i8 %inc2, i8* @a 161 %cmp2 = extractvalue { i8, i1 } %add_ov2, 1 162 %conv5 = zext i1 %cmp2 to i8 163 store i8 %conv5, i8* @d 164 br i1 %cmp, label %then, label %else 165 166then: 167 tail call void @external_a() 168 ret void 169 170else: 171 tail call void @external_b() 172 ret void 173} 174 175!llvm.module.flags = !{!0} 176!0 = !{i32 1, !"ProfileSummary", !1} 177!1 = !{!2, !3, !4, !5, !6, !7, !8, !9} 178!2 = !{!"ProfileFormat", !"InstrProf"} 179!3 = !{!"TotalCount", i64 10000} 180!4 = !{!"MaxCount", i64 10} 181!5 = !{!"MaxInternalCount", i64 1} 182!6 = !{!"MaxFunctionCount", i64 1000} 183!7 = !{!"NumCounts", i64 3} 184!8 = !{!"NumFunctions", i64 3} 185!9 = !{!"DetailedSummary", !10} 186!10 = !{!11, !12, !13} 187!11 = !{i32 10000, i64 100, i32 1} 188!12 = !{i32 999000, i64 100, i32 1} 189!13 = !{i32 999999, i64 1, i32 2} 190!14 = !{!"function_entry_count", i64 0} 191