Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mcpu=generic -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X32
      3 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s --check-prefixes=X64,X64-LINUX
      4 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-win32 | FileCheck %s --check-prefixes=X64,X64-WIN32
      5 
      6 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
      7 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
      8 
      9 ; The immediate can be encoded in a smaller way if the
     10 ; instruction is a sub instead of an add.
     11 define i32 @test1(i32 inreg %a) nounwind {
     12 ; X32-LABEL: test1:
     13 ; X32:       # %bb.0: # %entry
     14 ; X32-NEXT:    subl $-128, %eax
     15 ; X32-NEXT:    retl
     16 ;
     17 ; X64-LINUX-LABEL: test1:
     18 ; X64-LINUX:       # %bb.0: # %entry
     19 ; X64-LINUX-NEXT:    subl $-128, %edi
     20 ; X64-LINUX-NEXT:    movl %edi, %eax
     21 ; X64-LINUX-NEXT:    retq
     22 ;
     23 ; X64-WIN32-LABEL: test1:
     24 ; X64-WIN32:       # %bb.0: # %entry
     25 ; X64-WIN32-NEXT:    subl $-128, %ecx
     26 ; X64-WIN32-NEXT:    movl %ecx, %eax
     27 ; X64-WIN32-NEXT:    retq
     28 entry:
     29   %b = add i32 %a, 128
     30   ret i32 %b
     31 }
     32 define i64 @test2(i64 inreg %a) nounwind {
     33 ; X32-LABEL: test2:
     34 ; X32:       # %bb.0: # %entry
     35 ; X32-NEXT:    addl $-2147483648, %eax # imm = 0x80000000
     36 ; X32-NEXT:    adcl $0, %edx
     37 ; X32-NEXT:    retl
     38 ;
     39 ; X64-LINUX-LABEL: test2:
     40 ; X64-LINUX:       # %bb.0: # %entry
     41 ; X64-LINUX-NEXT:    subq $-2147483648, %rdi # imm = 0x80000000
     42 ; X64-LINUX-NEXT:    movq %rdi, %rax
     43 ; X64-LINUX-NEXT:    retq
     44 ;
     45 ; X64-WIN32-LABEL: test2:
     46 ; X64-WIN32:       # %bb.0: # %entry
     47 ; X64-WIN32-NEXT:    subq $-2147483648, %rcx # imm = 0x80000000
     48 ; X64-WIN32-NEXT:    movq %rcx, %rax
     49 ; X64-WIN32-NEXT:    retq
     50 entry:
     51   %b = add i64 %a, 2147483648
     52   ret i64 %b
     53 }
     54 define i64 @test3(i64 inreg %a) nounwind {
     55 ; X32-LABEL: test3:
     56 ; X32:       # %bb.0: # %entry
     57 ; X32-NEXT:    addl $128, %eax
     58 ; X32-NEXT:    adcl $0, %edx
     59 ; X32-NEXT:    retl
     60 ;
     61 ; X64-LINUX-LABEL: test3:
     62 ; X64-LINUX:       # %bb.0: # %entry
     63 ; X64-LINUX-NEXT:    subq $-128, %rdi
     64 ; X64-LINUX-NEXT:    movq %rdi, %rax
     65 ; X64-LINUX-NEXT:    retq
     66 ;
     67 ; X64-WIN32-LABEL: test3:
     68 ; X64-WIN32:       # %bb.0: # %entry
     69 ; X64-WIN32-NEXT:    subq $-128, %rcx
     70 ; X64-WIN32-NEXT:    movq %rcx, %rax
     71 ; X64-WIN32-NEXT:    retq
     72 entry:
     73   %b = add i64 %a, 128
     74   ret i64 %b
     75 }
     76 
     77 define i1 @test4(i32 %v1, i32 %v2, i32* %X) nounwind {
     78 ; X32-LABEL: test4:
     79 ; X32:       # %bb.0: # %entry
     80 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
     81 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
     82 ; X32-NEXT:    jo .LBB3_2
     83 ; X32-NEXT:  # %bb.1: # %normal
     84 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
     85 ; X32-NEXT:    movl $0, (%eax)
     86 ; X32-NEXT:  .LBB3_2: # %overflow
     87 ; X32-NEXT:    xorl %eax, %eax
     88 ; X32-NEXT:    retl
     89 ;
     90 ; X64-LINUX-LABEL: test4:
     91 ; X64-LINUX:       # %bb.0: # %entry
     92 ; X64-LINUX-NEXT:    addl %esi, %edi
     93 ; X64-LINUX-NEXT:    jo .LBB3_2
     94 ; X64-LINUX-NEXT:  # %bb.1: # %normal
     95 ; X64-LINUX-NEXT:    movl $0, (%rdx)
     96 ; X64-LINUX-NEXT:  .LBB3_2: # %overflow
     97 ; X64-LINUX-NEXT:    xorl %eax, %eax
     98 ; X64-LINUX-NEXT:    retq
     99 ;
    100 ; X64-WIN32-LABEL: test4:
    101 ; X64-WIN32:       # %bb.0: # %entry
    102 ; X64-WIN32-NEXT:    addl %edx, %ecx
    103 ; X64-WIN32-NEXT:    jo .LBB3_2
    104 ; X64-WIN32-NEXT:  # %bb.1: # %normal
    105 ; X64-WIN32-NEXT:    movl $0, (%r8)
    106 ; X64-WIN32-NEXT:  .LBB3_2: # %overflow
    107 ; X64-WIN32-NEXT:    xorl %eax, %eax
    108 ; X64-WIN32-NEXT:    retq
    109 entry:
    110   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
    111   %sum = extractvalue {i32, i1} %t, 0
    112   %obit = extractvalue {i32, i1} %t, 1
    113   br i1 %obit, label %overflow, label %normal
    114 
    115 normal:
    116   store i32 0, i32* %X
    117   br label %overflow
    118 
    119 overflow:
    120   ret i1 false
    121 }
    122 
    123 define i1 @test5(i32 %v1, i32 %v2, i32* %X) nounwind {
    124 ; X32-LABEL: test5:
    125 ; X32:       # %bb.0: # %entry
    126 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    127 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
    128 ; X32-NEXT:    jb .LBB4_2
    129 ; X32-NEXT:  # %bb.1: # %normal
    130 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    131 ; X32-NEXT:    movl $0, (%eax)
    132 ; X32-NEXT:  .LBB4_2: # %carry
    133 ; X32-NEXT:    xorl %eax, %eax
    134 ; X32-NEXT:    retl
    135 ;
    136 ; X64-LINUX-LABEL: test5:
    137 ; X64-LINUX:       # %bb.0: # %entry
    138 ; X64-LINUX-NEXT:    addl %esi, %edi
    139 ; X64-LINUX-NEXT:    jb .LBB4_2
    140 ; X64-LINUX-NEXT:  # %bb.1: # %normal
    141 ; X64-LINUX-NEXT:    movl $0, (%rdx)
    142 ; X64-LINUX-NEXT:  .LBB4_2: # %carry
    143 ; X64-LINUX-NEXT:    xorl %eax, %eax
    144 ; X64-LINUX-NEXT:    retq
    145 ;
    146 ; X64-WIN32-LABEL: test5:
    147 ; X64-WIN32:       # %bb.0: # %entry
    148 ; X64-WIN32-NEXT:    addl %edx, %ecx
    149 ; X64-WIN32-NEXT:    jb .LBB4_2
    150 ; X64-WIN32-NEXT:  # %bb.1: # %normal
    151 ; X64-WIN32-NEXT:    movl $0, (%r8)
    152 ; X64-WIN32-NEXT:  .LBB4_2: # %carry
    153 ; X64-WIN32-NEXT:    xorl %eax, %eax
    154 ; X64-WIN32-NEXT:    retq
    155 entry:
    156   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    157   %sum = extractvalue {i32, i1} %t, 0
    158   %obit = extractvalue {i32, i1} %t, 1
    159   br i1 %obit, label %carry, label %normal
    160 
    161 normal:
    162   store i32 0, i32* %X
    163   br label %carry
    164 
    165 carry:
    166   ret i1 false
    167 }
    168 
    169 define i64 @test6(i64 %A, i32 %B) nounwind {
    170 ; X32-LABEL: test6:
    171 ; X32:       # %bb.0: # %entry
    172 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    173 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
    174 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
    175 ; X32-NEXT:    retl
    176 ;
    177 ; X64-LINUX-LABEL: test6:
    178 ; X64-LINUX:       # %bb.0: # %entry
    179 ; X64-LINUX-NEXT:    # kill: def $esi killed $esi def $rsi
    180 ; X64-LINUX-NEXT:    shlq $32, %rsi
    181 ; X64-LINUX-NEXT:    leaq (%rsi,%rdi), %rax
    182 ; X64-LINUX-NEXT:    retq
    183 ;
    184 ; X64-WIN32-LABEL: test6:
    185 ; X64-WIN32:       # %bb.0: # %entry
    186 ; X64-WIN32-NEXT:    # kill: def $edx killed $edx def $rdx
    187 ; X64-WIN32-NEXT:    shlq $32, %rdx
    188 ; X64-WIN32-NEXT:    leaq (%rdx,%rcx), %rax
    189 ; X64-WIN32-NEXT:    retq
    190 entry:
    191   %tmp12 = zext i32 %B to i64
    192   %tmp3 = shl i64 %tmp12, 32
    193   %tmp5 = add i64 %tmp3, %A
    194   ret i64 %tmp5
    195 }
    196 
    197 define {i32, i1} @test7(i32 %v1, i32 %v2) nounwind {
    198 ; X32-LABEL: test7:
    199 ; X32:       # %bb.0: # %entry
    200 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    201 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
    202 ; X32-NEXT:    setb %dl
    203 ; X32-NEXT:    retl
    204 ;
    205 ; X64-LINUX-LABEL: test7:
    206 ; X64-LINUX:       # %bb.0: # %entry
    207 ; X64-LINUX-NEXT:    addl %esi, %edi
    208 ; X64-LINUX-NEXT:    setb %dl
    209 ; X64-LINUX-NEXT:    movl %edi, %eax
    210 ; X64-LINUX-NEXT:    retq
    211 ;
    212 ; X64-WIN32-LABEL: test7:
    213 ; X64-WIN32:       # %bb.0: # %entry
    214 ; X64-WIN32-NEXT:    addl %edx, %ecx
    215 ; X64-WIN32-NEXT:    setb %dl
    216 ; X64-WIN32-NEXT:    movl %ecx, %eax
    217 ; X64-WIN32-NEXT:    retq
    218 entry:
    219   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    220   ret {i32, i1} %t
    221 }
    222 
    223 ; PR5443
    224 define {i64, i1} @test8(i64 %left, i64 %right) nounwind {
    225 ; X32-LABEL: test8:
    226 ; X32:       # %bb.0: # %entry
    227 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    228 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
    229 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
    230 ; X32-NEXT:    adcl {{[0-9]+}}(%esp), %edx
    231 ; X32-NEXT:    setb %cl
    232 ; X32-NEXT:    retl
    233 ;
    234 ; X64-LINUX-LABEL: test8:
    235 ; X64-LINUX:       # %bb.0: # %entry
    236 ; X64-LINUX-NEXT:    addq %rsi, %rdi
    237 ; X64-LINUX-NEXT:    setb %dl
    238 ; X64-LINUX-NEXT:    movq %rdi, %rax
    239 ; X64-LINUX-NEXT:    retq
    240 ;
    241 ; X64-WIN32-LABEL: test8:
    242 ; X64-WIN32:       # %bb.0: # %entry
    243 ; X64-WIN32-NEXT:    addq %rdx, %rcx
    244 ; X64-WIN32-NEXT:    setb %dl
    245 ; X64-WIN32-NEXT:    movq %rcx, %rax
    246 ; X64-WIN32-NEXT:    retq
    247 entry:
    248   %extleft = zext i64 %left to i65
    249   %extright = zext i64 %right to i65
    250   %sum = add i65 %extleft, %extright
    251   %res.0 = trunc i65 %sum to i64
    252   %overflow = and i65 %sum, -18446744073709551616
    253   %res.1 = icmp ne i65 %overflow, 0
    254   %final0 = insertvalue {i64, i1} undef, i64 %res.0, 0
    255   %final1 = insertvalue {i64, i1} %final0, i1 %res.1, 1
    256   ret {i64, i1} %final1
    257 }
    258 
    259 define i32 @test9(i32 %x, i32 %y) nounwind readnone {
    260 ; X32-LABEL: test9:
    261 ; X32:       # %bb.0: # %entry
    262 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    263 ; X32-NEXT:    xorl %ecx, %ecx
    264 ; X32-NEXT:    cmpl $10, {{[0-9]+}}(%esp)
    265 ; X32-NEXT:    sete %cl
    266 ; X32-NEXT:    subl %ecx, %eax
    267 ; X32-NEXT:    retl
    268 ;
    269 ; X64-LINUX-LABEL: test9:
    270 ; X64-LINUX:       # %bb.0: # %entry
    271 ; X64-LINUX-NEXT:    xorl %eax, %eax
    272 ; X64-LINUX-NEXT:    cmpl $10, %edi
    273 ; X64-LINUX-NEXT:    sete %al
    274 ; X64-LINUX-NEXT:    subl %eax, %esi
    275 ; X64-LINUX-NEXT:    movl %esi, %eax
    276 ; X64-LINUX-NEXT:    retq
    277 ;
    278 ; X64-WIN32-LABEL: test9:
    279 ; X64-WIN32:       # %bb.0: # %entry
    280 ; X64-WIN32-NEXT:    xorl %eax, %eax
    281 ; X64-WIN32-NEXT:    cmpl $10, %ecx
    282 ; X64-WIN32-NEXT:    sete %al
    283 ; X64-WIN32-NEXT:    subl %eax, %edx
    284 ; X64-WIN32-NEXT:    movl %edx, %eax
    285 ; X64-WIN32-NEXT:    retq
    286 entry:
    287   %cmp = icmp eq i32 %x, 10
    288   %sub = sext i1 %cmp to i32
    289   %cond = add i32 %sub, %y
    290   ret i32 %cond
    291 }
    292 
    293 define i1 @test10(i32 %x) nounwind {
    294 ; X32-LABEL: test10:
    295 ; X32:       # %bb.0: # %entry
    296 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    297 ; X32-NEXT:    incl %eax
    298 ; X32-NEXT:    seto %al
    299 ; X32-NEXT:    retl
    300 ;
    301 ; X64-LINUX-LABEL: test10:
    302 ; X64-LINUX:       # %bb.0: # %entry
    303 ; X64-LINUX-NEXT:    incl %edi
    304 ; X64-LINUX-NEXT:    seto %al
    305 ; X64-LINUX-NEXT:    retq
    306 ;
    307 ; X64-WIN32-LABEL: test10:
    308 ; X64-WIN32:       # %bb.0: # %entry
    309 ; X64-WIN32-NEXT:    incl %ecx
    310 ; X64-WIN32-NEXT:    seto %al
    311 ; X64-WIN32-NEXT:    retq
    312 entry:
    313   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
    314   %obit = extractvalue {i32, i1} %t, 1
    315   ret i1 %obit
    316 }
    317 
    318 define void @test11(i32* inreg %a) nounwind {
    319 ; X32-LABEL: test11:
    320 ; X32:       # %bb.0: # %entry
    321 ; X32-NEXT:    subl $-128, (%eax)
    322 ; X32-NEXT:    retl
    323 ;
    324 ; X64-LINUX-LABEL: test11:
    325 ; X64-LINUX:       # %bb.0: # %entry
    326 ; X64-LINUX-NEXT:    subl $-128, (%rdi)
    327 ; X64-LINUX-NEXT:    retq
    328 ;
    329 ; X64-WIN32-LABEL: test11:
    330 ; X64-WIN32:       # %bb.0: # %entry
    331 ; X64-WIN32-NEXT:    subl $-128, (%rcx)
    332 ; X64-WIN32-NEXT:    retq
    333 entry:
    334   %aa = load i32, i32* %a
    335   %b = add i32 %aa, 128
    336   store i32 %b, i32* %a
    337   ret void
    338 }
    339 
    340 define void @test12(i64* inreg %a) nounwind {
    341 ; X32-LABEL: test12:
    342 ; X32:       # %bb.0: # %entry
    343 ; X32-NEXT:    addl $-2147483648, (%eax) # imm = 0x80000000
    344 ; X32-NEXT:    adcl $0, 4(%eax)
    345 ; X32-NEXT:    retl
    346 ;
    347 ; X64-LINUX-LABEL: test12:
    348 ; X64-LINUX:       # %bb.0: # %entry
    349 ; X64-LINUX-NEXT:    subq $-2147483648, (%rdi) # imm = 0x80000000
    350 ; X64-LINUX-NEXT:    retq
    351 ;
    352 ; X64-WIN32-LABEL: test12:
    353 ; X64-WIN32:       # %bb.0: # %entry
    354 ; X64-WIN32-NEXT:    subq $-2147483648, (%rcx) # imm = 0x80000000
    355 ; X64-WIN32-NEXT:    retq
    356 entry:
    357   %aa = load i64, i64* %a
    358   %b = add i64 %aa, 2147483648
    359   store i64 %b, i64* %a
    360   ret void
    361 }
    362 
    363 define void @test13(i64* inreg %a) nounwind {
    364 ; X32-LABEL: test13:
    365 ; X32:       # %bb.0: # %entry
    366 ; X32-NEXT:    addl $128, (%eax)
    367 ; X32-NEXT:    adcl $0, 4(%eax)
    368 ; X32-NEXT:    retl
    369 ;
    370 ; X64-LINUX-LABEL: test13:
    371 ; X64-LINUX:       # %bb.0: # %entry
    372 ; X64-LINUX-NEXT:    subq $-128, (%rdi)
    373 ; X64-LINUX-NEXT:    retq
    374 ;
    375 ; X64-WIN32-LABEL: test13:
    376 ; X64-WIN32:       # %bb.0: # %entry
    377 ; X64-WIN32-NEXT:    subq $-128, (%rcx)
    378 ; X64-WIN32-NEXT:    retq
    379 entry:
    380   %aa = load i64, i64* %a
    381   %b = add i64 %aa, 128
    382   store i64 %b, i64* %a
    383   ret void
    384 }
    385 
    386 define i32 @inc_not(i32 %a) {
    387 ; X32-LABEL: inc_not:
    388 ; X32:       # %bb.0:
    389 ; X32-NEXT:    xorl %eax, %eax
    390 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
    391 ; X32-NEXT:    retl
    392 ;
    393 ; X64-LINUX-LABEL: inc_not:
    394 ; X64-LINUX:       # %bb.0:
    395 ; X64-LINUX-NEXT:    negl %edi
    396 ; X64-LINUX-NEXT:    movl %edi, %eax
    397 ; X64-LINUX-NEXT:    retq
    398 ;
    399 ; X64-WIN32-LABEL: inc_not:
    400 ; X64-WIN32:       # %bb.0:
    401 ; X64-WIN32-NEXT:    negl %ecx
    402 ; X64-WIN32-NEXT:    movl %ecx, %eax
    403 ; X64-WIN32-NEXT:    retq
    404   %nota = xor i32 %a, -1
    405   %r = add i32 %nota, 1
    406   ret i32 %r
    407 }
    408 
    409 define void @uaddo1_not(i32 %a, i32* %p0, i1* %p1) {
    410 ; X32-LABEL: uaddo1_not:
    411 ; X32:       # %bb.0:
    412 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
    413 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    414 ; X32-NEXT:    xorl %edx, %edx
    415 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx
    416 ; X32-NEXT:    movl %edx, (%ecx)
    417 ; X32-NEXT:    setae (%eax)
    418 ; X32-NEXT:    retl
    419 ;
    420 ; X64-LINUX-LABEL: uaddo1_not:
    421 ; X64-LINUX:       # %bb.0:
    422 ; X64-LINUX-NEXT:    negl %edi
    423 ; X64-LINUX-NEXT:    movl %edi, (%rsi)
    424 ; X64-LINUX-NEXT:    setae (%rdx)
    425 ; X64-LINUX-NEXT:    retq
    426 ;
    427 ; X64-WIN32-LABEL: uaddo1_not:
    428 ; X64-WIN32:       # %bb.0:
    429 ; X64-WIN32-NEXT:    negl %ecx
    430 ; X64-WIN32-NEXT:    movl %ecx, (%rdx)
    431 ; X64-WIN32-NEXT:    setae (%r8)
    432 ; X64-WIN32-NEXT:    retq
    433   %nota = xor i32 %a, -1
    434   %uaddo = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %nota, i32 1)
    435   %r0 = extractvalue {i32, i1} %uaddo, 0
    436   %r1 = extractvalue {i32, i1} %uaddo, 1
    437   store i32 %r0, i32* %p0
    438   store i1 %r1, i1* %p1
    439   ret void
    440 }
    441