Home | History | Annotate | Download | only in SystemZ
      1 ; Test the three-operand form of 32-bit addition.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
      4 
      5 declare i32 @foo(i32, i32, i32)
      6 
      7 ; Check ALRK.
      8 define i32 @f1(i32 %dummy, i32 %a, i32 %b, i32 *%flag) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: alrk %r2, %r3, %r4
     11 ; CHECK: ipm [[REG1:%r[0-5]]]
     12 ; CHECK: risblg [[REG2:%r[0-5]]], [[REG1]], 31, 159, 35
     13 ; CHECK: st [[REG2]], 0(%r5)
     14 ; CHECK: br %r14
     15   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
     16   %val = extractvalue {i32, i1} %t, 0
     17   %obit = extractvalue {i32, i1} %t, 1
     18   %ext = zext i1 %obit to i32
     19   store i32 %ext, i32 *%flag
     20   ret i32 %val
     21 }
     22 
     23 ; Check using the overflow result for a branch.
     24 define i32 @f2(i32 %dummy, i32 %a, i32 %b) {
     25 ; CHECK-LABEL: f2:
     26 ; CHECK: alrk %r2, %r3, %r4
     27 ; CHECK-NEXT: bler %r14
     28 ; CHECK: lhi %r2, 0
     29 ; CHECK: jg foo@PLT
     30   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
     31   %val = extractvalue {i32, i1} %t, 0
     32   %obit = extractvalue {i32, i1} %t, 1
     33   br i1 %obit, label %call, label %exit
     34 
     35 call:
     36   %res = tail call i32 @foo(i32 0, i32 %a, i32 %b)
     37   ret i32 %res
     38 
     39 exit:
     40   ret i32 %val
     41 }
     42 
     43 ; ... and the same with the inverted direction.
     44 define i32 @f3(i32 %dummy, i32 %a, i32 %b) {
     45 ; CHECK-LABEL: f3:
     46 ; CHECK: alrk %r2, %r3, %r4
     47 ; CHECK-NEXT: bnler %r14
     48 ; CHECK: lhi %r2, 0
     49 ; CHECK: jg foo@PLT
     50   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
     51   %val = extractvalue {i32, i1} %t, 0
     52   %obit = extractvalue {i32, i1} %t, 1
     53   br i1 %obit, label %exit, label %call
     54 
     55 call:
     56   %res = tail call i32 @foo(i32 0, i32 %a, i32 %b)
     57   ret i32 %res
     58 
     59 exit:
     60   ret i32 %val
     61 }
     62 
     63 ; Check that we can still use ALR in obvious cases.
     64 define i32 @f4(i32 %a, i32 %b, i32 *%flag) {
     65 ; CHECK-LABEL: f4:
     66 ; CHECK: alr %r2, %r3
     67 ; CHECK: ipm [[REG1:%r[0-5]]]
     68 ; CHECK: risblg [[REG2:%r[0-5]]], [[REG1]], 31, 159, 35
     69 ; CHECK: st [[REG2]], 0(%r4)
     70 ; CHECK: br %r14
     71   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
     72   %val = extractvalue {i32, i1} %t, 0
     73   %obit = extractvalue {i32, i1} %t, 1
     74   %ext = zext i1 %obit to i32
     75   store i32 %ext, i32 *%flag
     76   ret i32 %val
     77 }
     78 
     79 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
     80 
     81