summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/ARM/su-addsub-overflow.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen/ARM/su-addsub-overflow.ll')
-rw-r--r--llvm/test/CodeGen/ARM/su-addsub-overflow.ll63
1 files changed, 47 insertions, 16 deletions
diff --git a/llvm/test/CodeGen/ARM/su-addsub-overflow.ll b/llvm/test/CodeGen/ARM/su-addsub-overflow.ll
index eef53128203..04e59e05b6d 100644
--- a/llvm/test/CodeGen/ARM/su-addsub-overflow.ll
+++ b/llvm/test/CodeGen/ARM/su-addsub-overflow.ll
@@ -2,9 +2,7 @@
define i32 @sadd(i32 %a, i32 %b) local_unnamed_addr #0 {
; CHECK-LABEL: sadd:
-; CHECK: mov r[[R0:[0-9]+]], r0
-; CHECK-NEXT: add r[[R1:[0-9]+]], r[[R0]], r1
-; CHECK-NEXT: cmp r[[R1]], r[[R0]]
+; CHECK: adds r0, r0, r1
; CHECK-NEXT: movvc pc, lr
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
@@ -23,10 +21,8 @@ cont:
define i32 @uadd(i32 %a, i32 %b) local_unnamed_addr #0 {
; CHECK-LABEL: uadd:
-; CHECK: mov r[[R0:[0-9]+]], r0
-; CHECK-NEXT: adds r[[R1:[0-9]+]], r[[R0]], r1
-; CHECK-NEXT: cmp r[[R1]], r[[R0]]
-; CHECK-NEXT: movhs pc, lr
+; CHECK: adds r0, r0, r1
+; CHECK-NEXT: movlo pc, lr
entry:
%0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
%1 = extractvalue { i32, i1 } %0, 1
@@ -44,8 +40,7 @@ cont:
define i32 @ssub(i32 %a, i32 %b) local_unnamed_addr #0 {
; CHECK-LABEL: ssub:
-; CHECK: cmp r0, r1
-; CHECK-NEXT: subvc r0, r0, r1
+; CHECK: subs r0, r0, r1
; CHECK-NEXT: movvc pc, lr
entry:
%0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
@@ -64,9 +59,7 @@ cont:
define i32 @usub(i32 %a, i32 %b) local_unnamed_addr #0 {
; CHECK-LABEL: usub:
-; CHECK: mov r[[R0:[0-9]+]], r0
-; CHECK-NEXT: subs r[[R1:[0-9]+]], r[[R0]], r1
-; CHECK-NEXT: cmp r[[R0]], r1
+; CHECK: subs r0, r0, r1
; CHECK-NEXT: movhs pc, lr
entry:
%0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
@@ -87,11 +80,9 @@ define void @sum(i32* %a, i32* %b, i32 %n) local_unnamed_addr #0 {
; CHECK-LABEL: sum:
; CHECK: ldr [[R0:r[0-9]+]],
; CHECK-NEXT: ldr [[R1:r[0-9]+|lr]],
-; CHECK-NEXT: add [[R2:r[0-9]+]], [[R1]], [[R0]]
-; CHECK-NEXT: cmp [[R2]], [[R1]]
+; CHECK-NEXT: adds [[R2:r[0-9]+]], [[R1]], [[R0]]
; CHECK-NEXT: strvc [[R2]],
-; CHECK-NEXT: addvc
-; CHECK-NEXT: cmpvc
+; CHECK-NEXT: addsvc
; CHECK-NEXT: bvs
entry:
%cmp7 = icmp eq i32 %n, 0
@@ -128,6 +119,46 @@ cont2:
}
+define void @extern_loop(i32 %n) local_unnamed_addr #0 {
+; Do not replace the compare around the clobbering call.
+; CHECK: add {{r[0-9]+}}, {{r[0-9]+}}, #1
+; CHECK-NEXT: bl external_fn
+; CHECK: cmp
+entry:
+ %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %n, i32 1)
+ %1 = extractvalue { i32, i1 } %0, 1
+ br i1 %1, label %trap, label %cont.lr.ph
+
+cont.lr.ph:
+ %2 = extractvalue { i32, i1 } %0, 0
+ %cmp5 = icmp sgt i32 %2, 0
+ br i1 %cmp5, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader:
+ br label %for.body
+
+trap:
+ tail call void @llvm.trap() #2
+ unreachable
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %i.046 = phi i32 [ %5, %cont1 ], [ 0, %for.body.preheader ]
+ tail call void bitcast (void (...)* @external_fn to void ()*)() #4
+ %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.046, i32 1)
+ %4 = extractvalue { i32, i1 } %3, 1
+ br i1 %4, label %trap, label %cont1
+
+cont1:
+ %5 = extractvalue { i32, i1 } %3, 0
+ %cmp = icmp slt i32 %5, %2
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+}
+
+declare void @external_fn(...) local_unnamed_addr #0
+
declare void @llvm.trap() #2
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #1
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1
OpenPOWER on IntegriCloud