summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/ARM/intrinsics-overflow.ll88
-rw-r--r--llvm/test/CodeGen/ARM/pr34045-2.ll25
-rw-r--r--llvm/test/CodeGen/ARM/pr34045.ll53
-rw-r--r--llvm/test/CodeGen/ARM/pr35103.ll43
4 files changed, 194 insertions, 15 deletions
diff --git a/llvm/test/CodeGen/ARM/intrinsics-overflow.ll b/llvm/test/CodeGen/ARM/intrinsics-overflow.ll
index af3dd9dd411..af555d2240c 100644
--- a/llvm/test/CodeGen/ARM/intrinsics-overflow.ll
+++ b/llvm/test/CodeGen/ARM/intrinsics-overflow.ll
@@ -1,4 +1,6 @@
-; RUN: llc < %s -mtriple=arm-linux -mcpu=generic | FileCheck %s
+; RUN: llc < %s -mtriple=arm-linux -mcpu=generic -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
+; RUN: llc < %s -mtriple=thumbv6m-eabi -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=THUMBV6
+; RUN: llc < %s -mtriple=thumbv7-eabi -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=THUMBV7
define i32 @uadd_overflow(i32 %a, i32 %b) #0 {
%sadd = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
@@ -7,10 +9,19 @@ define i32 @uadd_overflow(i32 %a, i32 %b) #0 {
ret i32 %2
; CHECK-LABEL: uadd_overflow:
- ; CHECK: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
- ; CHECK: mov r[[R1]], #1
- ; CHECK: cmp r[[R2]], r[[R0]]
- ; CHECK: movhs r[[R1]], #0
+
+ ; ARM: adds r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
+ ; ARM: mov r[[R2:[0-9]+]], #0
+ ; ARM: adc r[[R0]], r[[R2]], #0
+
+ ; THUMBV6: movs r[[R2:[0-9]+]], #0
+ ; THUMBV6: adds r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
+ ; THUMBV6: adcs r[[R2]], r[[R2]]
+ ; THUMBV6: mov r[[R0]], r[[R2]]
+
+ ; THUMBV7: adds r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
+ ; THUMBV7: mov.w r[[R2:[0-9]+]], #0
+ ; THUMBV7: adc r[[R0]], r[[R2]], #0
}
@@ -21,10 +32,26 @@ define i32 @sadd_overflow(i32 %a, i32 %b) #0 {
ret i32 %2
; CHECK-LABEL: sadd_overflow:
- ; CHECK: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
- ; CHECK: mov r[[R1]], #1
- ; CHECK: cmp r[[R2]], r[[R0]]
- ; CHECK: movvc r[[R1]], #0
+
+ ; ARM: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
+ ; ARM: mov r[[R1]], #1
+ ; ARM: cmp r[[R2]], r[[R0]]
+ ; ARM: movvc r[[R1]], #0
+
+ ; THUMBV6: mov r[[R2:[0-9]+]], r[[R0:[0-9]+]]
+ ; THUMBV6: adds r[[R3:[0-9]+]], r[[R2]], r[[R1:[0-9]+]]
+ ; THUMBV6: movs r[[R0]], #0
+ ; THUMBV6: movs r[[R1]], #1
+ ; THUMBV6: cmp r[[R3]], r[[R2]]
+ ; THUMBV6: bvc .L[[LABEL:.*]]
+ ; THUMBV6: mov r[[R0]], r[[R1]]
+ ; THUMBV6: .L[[LABEL]]:
+
+ ; THUMBV7: movs r[[R1]], #1
+ ; THUMBV7: cmp r[[R2]], r[[R0]]
+ ; THUMBV7: it vc
+ ; THUMBV7: movvc r[[R1]], #0
+ ; THUMBV7: mov r[[R0]], r[[R1]]
}
define i32 @usub_overflow(i32 %a, i32 %b) #0 {
@@ -34,9 +61,26 @@ define i32 @usub_overflow(i32 %a, i32 %b) #0 {
ret i32 %2
; CHECK-LABEL: usub_overflow:
- ; CHECK: mov r[[R2]], #1
- ; CHECK: cmp r[[R0]], r[[R1]]
- ; CHECK: movhs r[[R2]], #0
+
+ ; ARM: subs r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
+ ; ARM: mov r[[R2:[0-9]+]], #0
+ ; ARM: adc r[[R0]], r[[R2]], #0
+ ; ARM: rsb r[[R0]], r[[R0]], #1
+
+ ; THUMBV6: movs r[[R2:[0-9]+]], #0
+ ; THUMBV6: subs r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
+ ; THUMBV6: adcs r[[R2]], r[[R2]]
+ ; THUMBV6: movs r[[R0]], #1
+ ; THUMBV6: subs r[[R0]], r[[R0]], r[[R2]]
+
+ ; THUMBV7: subs r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
+ ; THUMBV7: mov.w r[[R2:[0-9]+]], #0
+ ; THUMBV7: adc r[[R0]], r[[R2]], #0
+ ; THUMBV7: rsb.w r[[R0]], r[[R0]], #1
+
+ ; We should know that the overflow is just 1 bit,
+ ; no need to clear any other bit
+ ; CHECK-NOT: and
}
define i32 @ssub_overflow(i32 %a, i32 %b) #0 {
@@ -46,9 +90,23 @@ define i32 @ssub_overflow(i32 %a, i32 %b) #0 {
ret i32 %2
; CHECK-LABEL: ssub_overflow:
- ; CHECK: mov r[[R2]], #1
- ; CHECK: cmp r[[R0]], r[[R1]]
- ; CHECK: movvc r[[R2]], #0
+
+ ; ARM: mov r[[R2]], #1
+ ; ARM: cmp r[[R0]], r[[R1]]
+ ; ARM: movvc r[[R2]], #0
+
+ ; THUMBV6: movs r[[R0]], #0
+ ; THUMBV6: movs r[[R3:[0-9]+]], #1
+ ; THUMBV6: cmp r[[R2]], r[[R1:[0-9]+]]
+ ; THUMBV6: bvc .L[[LABEL:.*]]
+ ; THUMBV6: mov r[[R0]], r[[R3]]
+ ; THUMBV6: .L[[LABEL]]:
+
+ ; THUMBV7: movs r[[R2:[0-9]+]], #1
+ ; THUMBV7: cmp r[[R0:[0-9]+]], r[[R1:[0-9]+]]
+ ; THUMBV7: it vc
+ ; THUMBV7: movvc r[[R2]], #0
+ ; THUMBV7: mov r[[R0]], r[[R2]]
}
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1
diff --git a/llvm/test/CodeGen/ARM/pr34045-2.ll b/llvm/test/CodeGen/ARM/pr34045-2.ll
new file mode 100644
index 00000000000..94bc3ea3e4f
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/pr34045-2.ll
@@ -0,0 +1,25 @@
+; RUN: llc < %s -mtriple thumbv7 | FileCheck %s
+
+define hidden void @foo(i32* %ptr, i1 zeroext %long_blocks) {
+entry:
+; This test is actually checking that no cycle is introduced but at least we
+; want to see one umull.
+; CHECK: umull
+ %0 = load i32, i32* %ptr, align 4
+ %conv.i.i13.i = zext i32 %0 to i64
+ %mul.i.i14.i = mul nuw nsw i64 %conv.i.i13.i, 18782
+ %1 = load i32, i32* undef, align 4
+ %conv4.i.i16.i = zext i32 %1 to i64
+ %add5.i.i17.i = add nuw nsw i64 %mul.i.i14.i, %conv4.i.i16.i
+ %shr.i.i18.i = lshr i64 %add5.i.i17.i, 32
+ %add10.i.i20.i = add nuw nsw i64 %shr.i.i18.i, %add5.i.i17.i
+ %conv11.i.i21.i = trunc i64 %add10.i.i20.i to i32
+ %x.0.neg.i.i26.i = sub i32 -2, %conv11.i.i21.i
+ %sub.i.i27.i = add i32 %x.0.neg.i.i26.i, 0
+ store i32 %sub.i.i27.i, i32* %ptr, align 4
+ br label %while.body.i
+
+while.body.i: ; preds = %while.body.i, %entry
+ br label %while.body.i
+}
+
diff --git a/llvm/test/CodeGen/ARM/pr34045.ll b/llvm/test/CodeGen/ARM/pr34045.ll
new file mode 100644
index 00000000000..5d52bfe591b
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/pr34045.ll
@@ -0,0 +1,53 @@
+; RUN: llc < %s -mtriple thumbv7 | FileCheck %s
+
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+define hidden void @bn_mul_comba8(i32* nocapture %r, i32* nocapture readonly %a, i32* nocapture readonly %b) local_unnamed_addr {
+entry:
+; This test is actually checking that no cycle is introduced but at least we
+; want to see a couple of umull and one umlal in the output
+; CHECK: umull
+; CHECK: umull
+; CHECK: umlal
+ %0 = load i32, i32* %a, align 4
+ %conv = zext i32 %0 to i64
+ %1 = load i32, i32* %b, align 4
+ %conv2 = zext i32 %1 to i64
+ %mul = mul nuw i64 %conv2, %conv
+ %shr = lshr i64 %mul, 32
+ %2 = load i32, i32* %a, align 4
+ %conv13 = zext i32 %2 to i64
+ %3 = load i32, i32* undef, align 4
+ %conv15 = zext i32 %3 to i64
+ %mul16 = mul nuw i64 %conv15, %conv13
+ %add18 = add i64 %mul16, %shr
+ %shr20 = lshr i64 %add18, 32
+ %conv21 = trunc i64 %shr20 to i32
+ %4 = load i32, i32* undef, align 4
+ %conv34 = zext i32 %4 to i64
+ %5 = load i32, i32* %b, align 4
+ %conv36 = zext i32 %5 to i64
+ %mul37 = mul nuw i64 %conv36, %conv34
+ %conv38 = and i64 %add18, 4294967295
+ %add39 = add i64 %mul37, %conv38
+ %shr41 = lshr i64 %add39, 32
+ %conv42 = trunc i64 %shr41 to i32
+ %add43 = add i32 %conv42, %conv21
+ %cmp44 = icmp ult i32 %add43, %conv42
+ %c1.1 = zext i1 %cmp44 to i32
+ %add65 = add i32 0, %c1.1
+ %add86 = add i32 %add65, 0
+ %add107 = add i32 %add86, 0
+ %conv124 = zext i32 %add107 to i64
+ %add125 = add i64 0, %conv124
+ %conv145 = and i64 %add125, 4294967295
+ %add146 = add i64 %conv145, 0
+ %conv166 = and i64 %add146, 4294967295
+ %add167 = add i64 %conv166, 0
+ %conv187 = and i64 %add167, 4294967295
+ %add188 = add i64 %conv187, 0
+ %conv189 = trunc i64 %add188 to i32
+ %arrayidx200 = getelementptr inbounds i32, i32* %r, i32 3
+ store i32 %conv189, i32* %arrayidx200, align 4
+ ret void
+}
+
diff --git a/llvm/test/CodeGen/ARM/pr35103.ll b/llvm/test/CodeGen/ARM/pr35103.ll
new file mode 100644
index 00000000000..4f0392f45fe
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/pr35103.ll
@@ -0,0 +1,43 @@
+; RUN: llc -O2 -mtriple arm < %s | FileCheck %s
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @foo(i32 %vreg0, i32 %vreg1, i32 %vreg2, i32 %vreg3, i32 %vreg4) local_unnamed_addr {
+entry:
+ %conv = zext i32 %vreg2 to i64
+ %conv1 = zext i32 %vreg0 to i64
+ %add2 = add nuw nsw i64 %conv, %conv1
+ %shr = lshr i64 %add2, 32
+ %conv4 = trunc i64 %shr to i32
+ %conv5 = and i64 %add2, 4294967295
+ %add8 = add nuw nsw i64 %conv5, %conv1
+ %shr9 = lshr i64 %add8, 32
+ %conv10 = trunc i64 %shr9 to i32
+ %add11 = add nuw nsw i32 %conv10, %conv4
+ %conv12 = zext i32 %vreg3 to i64
+ %conv14 = zext i32 %vreg1 to i64
+ %add15 = add nuw nsw i64 %conv12, %conv14
+ %shr16 = lshr i64 %add15, 32
+ %conv19 = zext i32 %vreg4 to i64
+ %add20 = add nuw nsw i64 %shr16, %conv19
+ %shr22 = lshr i64 %add20, 32
+ %conv23 = trunc i64 %shr22 to i32
+ %add24 = add nuw nsw i32 %add11, %conv23
+ ret i32 %add24
+
+; CHECK: push {r11, lr}
+; CHECK-NEXT: adds r2, r2, r0
+; CHECK-NEXT: mov r12, #0
+; CHECK-NEXT: adc lr, r12, #0
+; CHECK-NEXT: adds r0, r2, r0
+; CHECK-NEXT: ldr r2, [sp, #8]
+; CHECK-NEXT: adc r0, r12, #0
+; CHECK-NEXT: adds r1, r3, r1
+; The interesting bit is the next instruction which looks
+; like is computing a dead r1 but is actually computing a carry
+; for the final adc.
+; CHECK-NEXT: adcs r1, r2, #0
+; CHECK-NEXT: adc r0, r0, lr
+; CHECK-NEXT: pop {r11, lr}
+; CHECK-NEXT: mov pc, lr
+
+}
OpenPOWER on IntegriCloud