summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2017-10-09 15:15:09 +0000
committerAmara Emerson <aemerson@apple.com>2017-10-09 15:15:09 +0000
commit24ca39ce71e6312672f58d311b6bb6af727f9ca7 (patch)
tree92eafa5cc4f54c2eef848c11ce5d311a740a5331 /llvm/test
parent8557e2940813f25d017bed66bf03ac55db6381fa (diff)
downloadbcm5719-llvm-24ca39ce71e6312672f58d311b6bb6af727f9ca7.tar.gz
bcm5719-llvm-24ca39ce71e6312672f58d311b6bb6af727f9ca7.zip
[AArch64] Improve codegen for inverted overflow checking intrinsics
E.g. if we have a (xor(overflow-bit), 1) where overflow-bit comes from an intrinsic like llvm.sadd.with.overflow then we can kill the xor and use the inverted condition code for the CSEL. rdar://28495949 Reviewed By: kristof.beyls Differential Revision: https://reviews.llvm.org/D38160 llvm-svn: 315205
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/AArch64/arm64-xaluo.ll138
1 files changed, 138 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AArch64/arm64-xaluo.ll b/llvm/test/CodeGen/AArch64/arm64-xaluo.ll
index 8b212aa6c1d..fc167d2f34d 100644
--- a/llvm/test/CodeGen/AArch64/arm64-xaluo.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-xaluo.ll
@@ -282,6 +282,17 @@ entry:
ret i32 %ret
}
+define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
+entry:
+; CHECK-LABEL: saddo.not.i32
+; CHECK: cmn w0, w1
+; CHECK-NEXT: cset w0, vc
+ %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
+ %obit = extractvalue {i32, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: saddo.select.i64
@@ -293,6 +304,17 @@ entry:
ret i64 %ret
}
+define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
+entry:
+; CHECK-LABEL: saddo.not.i64
+; CHECK: cmn x0, x1
+; CHECK-NEXT: cset w0, vc
+ %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
+ %obit = extractvalue {i64, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: uaddo.select.i32
@@ -304,6 +326,17 @@ entry:
ret i32 %ret
}
+define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
+entry:
+; CHECK-LABEL: uaddo.not.i32
+; CHECK: cmn w0, w1
+; CHECK-NEXT: cset w0, lo
+ %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
+ %obit = extractvalue {i32, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: uaddo.select.i64
@@ -315,6 +348,17 @@ entry:
ret i64 %ret
}
+define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
+entry:
+; CHECK-LABEL: uaddo.not.i64
+; CHECK: cmn x0, x1
+; CHECK-NEXT: cset w0, lo
+ %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
+ %obit = extractvalue {i64, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: ssubo.select.i32
@@ -326,6 +370,17 @@ entry:
ret i32 %ret
}
+define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
+entry:
+; CHECK-LABEL: ssubo.not.i32
+; CHECK: cmp w0, w1
+; CHECK-NEXT: cset w0, vc
+ %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
+ %obit = extractvalue {i32, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: ssubo.select.i64
@@ -337,6 +392,17 @@ entry:
ret i64 %ret
}
+define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
+entry:
+; CHECK-LABEL: ssub.not.i64
+; CHECK: cmp x0, x1
+; CHECK-NEXT: cset w0, vc
+ %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
+ %obit = extractvalue {i64, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: usubo.select.i32
@@ -348,6 +414,17 @@ entry:
ret i32 %ret
}
+define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
+entry:
+; CHECK-LABEL: usubo.not.i32
+; CHECK: cmp w0, w1
+; CHECK-NEXT: cset w0, hs
+ %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
+ %obit = extractvalue {i32, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: usubo.select.i64
@@ -359,6 +436,17 @@ entry:
ret i64 %ret
}
+define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
+entry:
+; CHECK-LABEL: usubo.not.i64
+; CHECK: cmp x0, x1
+; CHECK-NEXT: cset w0, hs
+ %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
+ %obit = extractvalue {i64, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: smulo.select.i32
@@ -372,6 +460,19 @@ entry:
ret i32 %ret
}
+define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
+entry:
+; CHECK-LABEL: smulo.not.i32
+; CHECK: smull x[[MREG:[0-9]+]], w0, w1
+; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32
+; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31
+; CHECK-NEXT: cset w0, eq
+ %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
+ %obit = extractvalue {i32, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: smulo.select.i64
@@ -385,6 +486,19 @@ entry:
ret i64 %ret
}
+define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
+entry:
+; CHECK-LABEL: smulo.not.i64
+; CHECK: mul [[MREG:x[0-9]+]], x0, x1
+; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
+; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
+; CHECK-NEXT: cset w0, eq
+ %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
+ %obit = extractvalue {i64, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: umulo.select.i32
@@ -397,6 +511,18 @@ entry:
ret i32 %ret
}
+define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
+entry:
+; CHECK-LABEL: umulo.not.i32
+; CHECK: umull [[MREG:x[0-9]+]], w0, w1
+; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32
+; CHECK-NEXT: cset w0, eq
+ %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
+ %obit = extractvalue {i32, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: umulo.select.i64
@@ -409,6 +535,18 @@ entry:
ret i64 %ret
}
+define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
+entry:
+; CHECK-LABEL: umulo.not.i64
+; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
+; CHECK-NEXT: cmp xzr, [[MREG]]
+; CHECK-NEXT: cset w0, eq
+ %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
+ %obit = extractvalue {i64, i1} %t, 1
+ %ret = xor i1 %obit, true
+ ret i1 %ret
+}
+
;
; Check the use of the overflow bit in combination with a branch instruction.
OpenPOWER on IntegriCloud