aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/SystemZ
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/SystemZ')
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-01.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-02.py2
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-03.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-04.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-05.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-06.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-09.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-10.py4
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-11.py8
-rw-r--r--test/CodeGen/SystemZ/Large/branch-range-12.py8
-rw-r--r--test/CodeGen/SystemZ/Large/lit.local.cfg3
-rw-r--r--test/CodeGen/SystemZ/atomic-load-01.ll5
-rw-r--r--test/CodeGen/SystemZ/atomic-load-02.ll5
-rw-r--r--test/CodeGen/SystemZ/atomic-load-03.ll8
-rw-r--r--test/CodeGen/SystemZ/atomic-load-04.ll8
-rw-r--r--test/CodeGen/SystemZ/atomic-store-01.ll5
-rw-r--r--test/CodeGen/SystemZ/atomic-store-02.ll5
-rw-r--r--test/CodeGen/SystemZ/atomic-store-03.ll8
-rw-r--r--test/CodeGen/SystemZ/atomic-store-04.ll8
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-add-05.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-add-06.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-and-05.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-and-06.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-or-05.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-or-06.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-sub-05.ll69
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-sub-06.ll69
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-xor-05.ll64
-rw-r--r--test/CodeGen/SystemZ/atomicrmw-xor-06.ll64
-rw-r--r--test/CodeGen/SystemZ/cmpxchg-01.ll6
-rw-r--r--test/CodeGen/SystemZ/cmpxchg-02.ll6
-rw-r--r--test/CodeGen/SystemZ/cmpxchg-03.ll36
-rw-r--r--test/CodeGen/SystemZ/cmpxchg-04.ll27
-rw-r--r--test/CodeGen/SystemZ/cond-store-01.ll7
-rw-r--r--test/CodeGen/SystemZ/cond-store-02.ll7
-rw-r--r--test/CodeGen/SystemZ/cond-store-03.ll4
-rw-r--r--test/CodeGen/SystemZ/cond-store-04.ll4
-rw-r--r--test/CodeGen/SystemZ/fp-cmp-04.ll61
-rw-r--r--test/CodeGen/SystemZ/fp-conv-06.ll4
-rw-r--r--test/CodeGen/SystemZ/fp-conv-08.ll4
-rw-r--r--test/CodeGen/SystemZ/fp-conv-10.ll4
-rw-r--r--test/CodeGen/SystemZ/fp-conv-12.ll4
-rw-r--r--test/CodeGen/SystemZ/fp-conv-13.ll64
-rw-r--r--test/CodeGen/SystemZ/fp-conv-14.ll63
-rw-r--r--test/CodeGen/SystemZ/frame-08.ll4
-rw-r--r--test/CodeGen/SystemZ/frame-11.ll13
-rw-r--r--test/CodeGen/SystemZ/frame-13.ll13
-rw-r--r--test/CodeGen/SystemZ/frame-14.ll14
-rw-r--r--test/CodeGen/SystemZ/insert-06.ll14
-rw-r--r--test/CodeGen/SystemZ/int-abs-01.ll64
-rw-r--r--test/CodeGen/SystemZ/int-cmp-05.ll17
-rw-r--r--test/CodeGen/SystemZ/int-cmp-06.ll30
-rw-r--r--test/CodeGen/SystemZ/int-cmp-44.ll92
-rw-r--r--test/CodeGen/SystemZ/int-cmp-45.ll2
-rw-r--r--test/CodeGen/SystemZ/int-cmp-47.ll109
-rw-r--r--test/CodeGen/SystemZ/int-neg-02.ll133
-rw-r--r--test/CodeGen/SystemZ/lit.local.cfg3
-rw-r--r--test/CodeGen/SystemZ/mature-mc-support.ll15
-rw-r--r--test/CodeGen/SystemZ/risbg-01.ll26
-rw-r--r--test/CodeGen/SystemZ/rnsbg-01.ll11
-rw-r--r--test/CodeGen/SystemZ/rosbg-01.ll11
-rw-r--r--test/CodeGen/SystemZ/rxsbg-01.ll11
-rw-r--r--test/CodeGen/SystemZ/selectcc-01.ll178
-rw-r--r--test/CodeGen/SystemZ/selectcc-02.ll178
-rw-r--r--test/CodeGen/SystemZ/selectcc-03.ll187
-rw-r--r--test/CodeGen/SystemZ/serialize-01.ll21
-rw-r--r--test/CodeGen/SystemZ/shift-04.ll101
-rw-r--r--test/CodeGen/SystemZ/shift-10.ll19
-rw-r--r--test/CodeGen/SystemZ/spill-01.ll2
69 files changed, 2167 insertions, 153 deletions
diff --git a/test/CodeGen/SystemZ/Large/branch-range-01.py b/test/CodeGen/SystemZ/Large/branch-range-01.py
index 552c9ca0ea85..edb631d8c6d5 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-01.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-01.py
@@ -79,7 +79,7 @@ for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
print ' %%bstop%d = getelementptr i32 *%%stop, i64 %d' % (i, i)
- print ' %%bcur%d = load volatile i32 *%%bstop%d' % (i, i)
+ print ' %%bcur%d = load i32 *%%bstop%d' % (i, i)
print ' %%btest%d = icmp eq i32 %%limit, %%bcur%d' % (i, i)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
print ''
@@ -95,7 +95,7 @@ for i in xrange(0, main_size, 6):
for i in xrange(branch_blocks):
print ' %%astop%d = getelementptr i32 *%%stop, i64 %d' % (i, i + 25)
- print ' %%acur%d = load volatile i32 *%%astop%d' % (i, i)
+ print ' %%acur%d = load i32 *%%astop%d' % (i, i)
print ' %%atest%d = icmp eq i32 %%limit, %%acur%d' % (i, i)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
print ''
diff --git a/test/CodeGen/SystemZ/Large/branch-range-02.py b/test/CodeGen/SystemZ/Large/branch-range-02.py
index 0b21ced99a1f..743e12de0f1f 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-02.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-02.py
@@ -72,7 +72,7 @@ for i in xrange(blocks):
print 'b%d:' % i
print ' store volatile i8 %d, i8 *%%base' % value
print ' %%astop%d = getelementptr i32 *%%stop, i64 %d' % (i, i)
- print ' %%acur%d = load volatile i32 *%%astop%d' % (i, i)
+ print ' %%acur%d = load i32 *%%astop%d' % (i, i)
print ' %%atest%d = icmp eq i32 %%limit, %%acur%d' % (i, i)
print ' br i1 %%atest%d, label %%%s, label %%%s' % (i, other, next)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-03.py b/test/CodeGen/SystemZ/Large/branch-range-03.py
index 75cdf247c6f3..5c9a93b87f73 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-03.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-03.py
@@ -79,7 +79,7 @@ for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
print ' %%bstop%d = getelementptr i8 *%%stop, i64 %d' % (i, i)
- print ' %%bcur%d = load volatile i8 *%%bstop%d' % (i, i)
+ print ' %%bcur%d = load i8 *%%bstop%d' % (i, i)
print ' %%bext%d = sext i8 %%bcur%d to i32' % (i, i)
print ' %%btest%d = icmp eq i32 %%limit, %%bext%d' % (i, i)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -96,7 +96,7 @@ for i in xrange(0, main_size, 6):
for i in xrange(branch_blocks):
print ' %%astop%d = getelementptr i8 *%%stop, i64 %d' % (i, i + 25)
- print ' %%acur%d = load volatile i8 *%%astop%d' % (i, i)
+ print ' %%acur%d = load i8 *%%astop%d' % (i, i)
print ' %%aext%d = sext i8 %%acur%d to i32' % (i, i)
print ' %%atest%d = icmp eq i32 %%limit, %%aext%d' % (i, i)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-04.py b/test/CodeGen/SystemZ/Large/branch-range-04.py
index 3ae3ae9c37f7..2c9090fa2067 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-04.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-04.py
@@ -83,7 +83,7 @@ for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
print ' %%bstop%d = getelementptr i8 *%%stop, i64 %d' % (i, i)
- print ' %%bcur%d = load volatile i8 *%%bstop%d' % (i, i)
+ print ' %%bcur%d = load i8 *%%bstop%d' % (i, i)
print ' %%bext%d = sext i8 %%bcur%d to i64' % (i, i)
print ' %%btest%d = icmp eq i64 %%limit, %%bext%d' % (i, i)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -100,7 +100,7 @@ for i in xrange(0, main_size, 6):
for i in xrange(branch_blocks):
print ' %%astop%d = getelementptr i8 *%%stop, i64 %d' % (i, i + 25)
- print ' %%acur%d = load volatile i8 *%%astop%d' % (i, i)
+ print ' %%acur%d = load i8 *%%astop%d' % (i, i)
print ' %%aext%d = sext i8 %%acur%d to i64' % (i, i)
print ' %%atest%d = icmp eq i64 %%limit, %%aext%d' % (i, i)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-05.py b/test/CodeGen/SystemZ/Large/branch-range-05.py
index 6928b8fc21d6..52f4a961c88f 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-05.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-05.py
@@ -82,7 +82,7 @@ print ''
for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
- print ' %%bcur%d = load volatile i8 *%%stop' % i
+ print ' %%bcur%d = load i8 *%%stop' % i
print ' %%bext%d = sext i8 %%bcur%d to i32' % (i, i)
print ' %%btest%d = icmp slt i32 %%bext%d, %d' % (i, i, i + 50)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -98,7 +98,7 @@ for i in xrange(0, main_size, 6):
print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i)
for i in xrange(branch_blocks):
- print ' %%acur%d = load volatile i8 *%%stop' % i
+ print ' %%acur%d = load i8 *%%stop' % i
print ' %%aext%d = sext i8 %%acur%d to i32' % (i, i)
print ' %%atest%d = icmp slt i32 %%aext%d, %d' % (i, i, i + 100)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-06.py b/test/CodeGen/SystemZ/Large/branch-range-06.py
index aabc72fa6ec8..c34ebac4ce36 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-06.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-06.py
@@ -82,7 +82,7 @@ print ''
for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
- print ' %%bcur%d = load volatile i8 *%%stop' % i
+ print ' %%bcur%d = load i8 *%%stop' % i
print ' %%bext%d = sext i8 %%bcur%d to i64' % (i, i)
print ' %%btest%d = icmp slt i64 %%bext%d, %d' % (i, i, i + 50)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -98,7 +98,7 @@ for i in xrange(0, main_size, 6):
print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i)
for i in xrange(branch_blocks):
- print ' %%acur%d = load volatile i8 *%%stop' % i
+ print ' %%acur%d = load i8 *%%stop' % i
print ' %%aext%d = sext i8 %%acur%d to i64' % (i, i)
print ' %%atest%d = icmp slt i64 %%aext%d, %d' % (i, i, i + 100)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-09.py b/test/CodeGen/SystemZ/Large/branch-range-09.py
index b3fd81324dab..bc712cb164ea 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-09.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-09.py
@@ -79,7 +79,7 @@ for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
print ' %%bstop%d = getelementptr i8 *%%stop, i64 %d' % (i, i)
- print ' %%bcur%d = load volatile i8 *%%bstop%d' % (i, i)
+ print ' %%bcur%d = load i8 *%%bstop%d' % (i, i)
print ' %%bext%d = sext i8 %%bcur%d to i32' % (i, i)
print ' %%btest%d = icmp ult i32 %%limit, %%bext%d' % (i, i)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -96,7 +96,7 @@ for i in xrange(0, main_size, 6):
for i in xrange(branch_blocks):
print ' %%astop%d = getelementptr i8 *%%stop, i64 %d' % (i, i + 25)
- print ' %%acur%d = load volatile i8 *%%astop%d' % (i, i)
+ print ' %%acur%d = load i8 *%%astop%d' % (i, i)
print ' %%aext%d = sext i8 %%acur%d to i32' % (i, i)
print ' %%atest%d = icmp ult i32 %%limit, %%aext%d' % (i, i)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-10.py b/test/CodeGen/SystemZ/Large/branch-range-10.py
index 3aeea3ebccdf..8c483c33724c 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-10.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-10.py
@@ -83,7 +83,7 @@ for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
print ' %%bstop%d = getelementptr i8 *%%stop, i64 %d' % (i, i)
- print ' %%bcur%d = load volatile i8 *%%bstop%d' % (i, i)
+ print ' %%bcur%d = load i8 *%%bstop%d' % (i, i)
print ' %%bext%d = sext i8 %%bcur%d to i64' % (i, i)
print ' %%btest%d = icmp ult i64 %%limit, %%bext%d' % (i, i)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -100,7 +100,7 @@ for i in xrange(0, main_size, 6):
for i in xrange(branch_blocks):
print ' %%astop%d = getelementptr i8 *%%stop, i64 %d' % (i, i + 25)
- print ' %%acur%d = load volatile i8 *%%astop%d' % (i, i)
+ print ' %%acur%d = load i8 *%%astop%d' % (i, i)
print ' %%aext%d = sext i8 %%acur%d to i64' % (i, i)
print ' %%atest%d = icmp ult i64 %%limit, %%aext%d' % (i, i)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-11.py b/test/CodeGen/SystemZ/Large/branch-range-11.py
index 034902c4a342..054610380e31 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-11.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-11.py
@@ -98,8 +98,8 @@ print ''
for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
- print ' %%bcur%da = load volatile i32 *%%stopa' % i
- print ' %%bcur%db = load volatile i32 *%%stopb' % i
+ print ' %%bcur%da = load i32 *%%stopa' % i
+ print ' %%bcur%db = load i32 *%%stopb' % i
print ' %%bsub%d = sub i32 %%bcur%da, %%bcur%db' % (i, i, i)
print ' %%btest%d = icmp ult i32 %%bsub%d, %d' % (i, i, i + 50)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -115,8 +115,8 @@ for i in xrange(0, main_size, 6):
print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i)
for i in xrange(branch_blocks):
- print ' %%acur%da = load volatile i32 *%%stopa' % i
- print ' %%acur%db = load volatile i32 *%%stopb' % i
+ print ' %%acur%da = load i32 *%%stopa' % i
+ print ' %%acur%db = load i32 *%%stopb' % i
print ' %%asub%d = sub i32 %%acur%da, %%acur%db' % (i, i, i)
print ' %%atest%d = icmp ult i32 %%asub%d, %d' % (i, i, i + 100)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/branch-range-12.py b/test/CodeGen/SystemZ/Large/branch-range-12.py
index 007d477e2140..626c8998d5d4 100644
--- a/test/CodeGen/SystemZ/Large/branch-range-12.py
+++ b/test/CodeGen/SystemZ/Large/branch-range-12.py
@@ -98,8 +98,8 @@ print ''
for i in xrange(branch_blocks):
next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
print 'before%d:' % i
- print ' %%bcur%da = load volatile i64 *%%stopa' % i
- print ' %%bcur%db = load volatile i64 *%%stopb' % i
+ print ' %%bcur%da = load i64 *%%stopa' % i
+ print ' %%bcur%db = load i64 *%%stopb' % i
print ' %%bsub%d = sub i64 %%bcur%da, %%bcur%db' % (i, i, i)
print ' %%btest%d = icmp ult i64 %%bsub%d, %d' % (i, i, i + 50)
print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
@@ -115,8 +115,8 @@ for i in xrange(0, main_size, 6):
print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i)
for i in xrange(branch_blocks):
- print ' %%acur%da = load volatile i64 *%%stopa' % i
- print ' %%acur%db = load volatile i64 *%%stopb' % i
+ print ' %%acur%da = load i64 *%%stopa' % i
+ print ' %%acur%db = load i64 *%%stopb' % i
print ' %%asub%d = sub i64 %%acur%da, %%acur%db' % (i, i, i)
print ' %%atest%d = icmp ult i64 %%asub%d, %d' % (i, i, i + 100)
print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
diff --git a/test/CodeGen/SystemZ/Large/lit.local.cfg b/test/CodeGen/SystemZ/Large/lit.local.cfg
index 9a02f849c347..4f22a970c3a6 100644
--- a/test/CodeGen/SystemZ/Large/lit.local.cfg
+++ b/test/CodeGen/SystemZ/Large/lit.local.cfg
@@ -5,6 +5,5 @@ config.suffixes = ['.py']
if config.root.host_arch not in ['SystemZ']:
config.unsupported = True
-targets = set(config.root.targets_to_build.split())
-if not 'SystemZ' in targets:
+if not 'SystemZ' in config.root.targets:
config.unsupported = True
diff --git a/test/CodeGen/SystemZ/atomic-load-01.ll b/test/CodeGen/SystemZ/atomic-load-01.ll
index a5bc8833e78a..f3acd605b012 100644
--- a/test/CodeGen/SystemZ/atomic-load-01.ll
+++ b/test/CodeGen/SystemZ/atomic-load-01.ll
@@ -2,11 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that loads are handled.
-; The CS-based sequence is probably far too conservative.
define i8 @f1(i8 *%src) {
; CHECK-LABEL: f1:
-; CHECK: cs
+; CHECK: bcr 1{{[45]}}, %r0
+; CHECK: lb %r2, 0(%r2)
; CHECK: br %r14
%val = load atomic i8 *%src seq_cst, align 1
ret i8 %val
diff --git a/test/CodeGen/SystemZ/atomic-load-02.ll b/test/CodeGen/SystemZ/atomic-load-02.ll
index 2c9bbdb488a1..d9bec60f4c1b 100644
--- a/test/CodeGen/SystemZ/atomic-load-02.ll
+++ b/test/CodeGen/SystemZ/atomic-load-02.ll
@@ -2,11 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that loads are handled.
-; The CS-based sequence is probably far too conservative.
define i16 @f1(i16 *%src) {
; CHECK-LABEL: f1:
-; CHECK: cs
+; CHECK: bcr 1{{[45]}}, %r0
+; CHECK: lh %r2, 0(%r2)
; CHECK: br %r14
%val = load atomic i16 *%src seq_cst, align 2
ret i16 %val
diff --git a/test/CodeGen/SystemZ/atomic-load-03.ll b/test/CodeGen/SystemZ/atomic-load-03.ll
index 1fb41f5e39aa..7e5eb9249a93 100644
--- a/test/CodeGen/SystemZ/atomic-load-03.ll
+++ b/test/CodeGen/SystemZ/atomic-load-03.ll
@@ -2,12 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that loads are handled.
-; Using CS is probably too conservative.
-define i32 @f1(i32 %dummy, i32 *%src) {
+define i32 @f1(i32 *%src) {
; CHECK-LABEL: f1:
-; CHECK: lhi %r2, 0
-; CHECK: cs %r2, %r2, 0(%r3)
+; CHECK: bcr 1{{[45]}}, %r0
+; CHECK: l %r2, 0(%r2)
; CHECK: br %r14
%val = load atomic i32 *%src seq_cst, align 4
ret i32 %val
diff --git a/test/CodeGen/SystemZ/atomic-load-04.ll b/test/CodeGen/SystemZ/atomic-load-04.ll
index 92cac406e200..c7a9a98a425d 100644
--- a/test/CodeGen/SystemZ/atomic-load-04.ll
+++ b/test/CodeGen/SystemZ/atomic-load-04.ll
@@ -2,12 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that loads are handled.
-; Using CSG is probably too conservative.
-define i64 @f1(i64 %dummy, i64 *%src) {
+define i64 @f1(i64 *%src) {
; CHECK-LABEL: f1:
-; CHECK: lghi %r2, 0
-; CHECK: csg %r2, %r2, 0(%r3)
+; CHECK: bcr 1{{[45]}}, %r0
+; CHECK: lg %r2, 0(%r2)
; CHECK: br %r14
%val = load atomic i64 *%src seq_cst, align 8
ret i64 %val
diff --git a/test/CodeGen/SystemZ/atomic-store-01.ll b/test/CodeGen/SystemZ/atomic-store-01.ll
index 53ed24f623cf..952e1a912168 100644
--- a/test/CodeGen/SystemZ/atomic-store-01.ll
+++ b/test/CodeGen/SystemZ/atomic-store-01.ll
@@ -2,11 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that stores are handled.
-; The CS-based sequence is probably far too conservative.
define void @f1(i8 %val, i8 *%src) {
; CHECK-LABEL: f1:
-; CHECK: cs
+; CHECK: stc %r2, 0(%r3)
+; CHECK: bcr 1{{[45]}}, %r0
; CHECK: br %r14
store atomic i8 %val, i8 *%src seq_cst, align 1
ret void
diff --git a/test/CodeGen/SystemZ/atomic-store-02.ll b/test/CodeGen/SystemZ/atomic-store-02.ll
index 42d6695b51d9..c9576e556566 100644
--- a/test/CodeGen/SystemZ/atomic-store-02.ll
+++ b/test/CodeGen/SystemZ/atomic-store-02.ll
@@ -2,11 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that stores are handled.
-; The CS-based sequence is probably far too conservative.
define void @f1(i16 %val, i16 *%src) {
; CHECK-LABEL: f1:
-; CHECK: cs
+; CHECK: sth %r2, 0(%r3)
+; CHECK: bcr 1{{[45]}}, %r0
; CHECK: br %r14
store atomic i16 %val, i16 *%src seq_cst, align 2
ret void
diff --git a/test/CodeGen/SystemZ/atomic-store-03.ll b/test/CodeGen/SystemZ/atomic-store-03.ll
index 846c86fd3662..459cb6a94e12 100644
--- a/test/CodeGen/SystemZ/atomic-store-03.ll
+++ b/test/CodeGen/SystemZ/atomic-store-03.ll
@@ -2,14 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that stores are handled.
-; Using CS is probably too conservative.
define void @f1(i32 %val, i32 *%src) {
; CHECK-LABEL: f1:
-; CHECK: l %r0, 0(%r3)
-; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: cs %r0, %r2, 0(%r3)
-; CHECK: jl [[LABEL]]
+; CHECK: st %r2, 0(%r3)
+; CHECK: bcr 1{{[45]}}, %r0
; CHECK: br %r14
store atomic i32 %val, i32 *%src seq_cst, align 4
ret void
diff --git a/test/CodeGen/SystemZ/atomic-store-04.ll b/test/CodeGen/SystemZ/atomic-store-04.ll
index 24615b115658..7f2406eb5468 100644
--- a/test/CodeGen/SystemZ/atomic-store-04.ll
+++ b/test/CodeGen/SystemZ/atomic-store-04.ll
@@ -2,14 +2,10 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-; This is just a placeholder to make sure that stores are handled.
-; Using CS is probably too conservative.
define void @f1(i64 %val, i64 *%src) {
; CHECK-LABEL: f1:
-; CHECK: lg %r0, 0(%r3)
-; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: csg %r0, %r2, 0(%r3)
-; CHECK: jl [[LABEL]]
+; CHECK: stg %r2, 0(%r3)
+; CHECK: bcr 1{{[45]}}, %r0
; CHECK: br %r14
store atomic i64 %val, i64 *%src seq_cst, align 8
ret void
diff --git a/test/CodeGen/SystemZ/atomicrmw-add-05.ll b/test/CodeGen/SystemZ/atomicrmw-add-05.ll
new file mode 100644
index 000000000000..956c0d9642cd
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-add-05.ll
@@ -0,0 +1,64 @@
+; Test 32-bit atomic additions, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check addition of a variable.
+define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f1:
+; CHECK: laa %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw add i32 *%src, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check addition of 1, which needs a temporary.
+define i32 @f2(i32 %dummy, i32 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lhi [[TMP:%r[0-5]]], 1
+; CHECK: laa %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw add i32 *%src, i32 1 seq_cst
+ ret i32 %res
+}
+
+; Check the high end of the LAA range.
+define i32 @f3(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f3:
+; CHECK: laa %r2, %r4, 524284(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131071
+ %res = atomicrmw add i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word up, which needs separate address logic.
+define i32 @f4(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: laa %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131072
+ %res = atomicrmw add i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the low end of the LAA range.
+define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f5:
+; CHECK: laa %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131072
+ %res = atomicrmw add i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word down, which needs separate address logic.
+define i32 @f6(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524292
+; CHECK: laa %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131073
+ %res = atomicrmw add i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-add-06.ll b/test/CodeGen/SystemZ/atomicrmw-add-06.ll
new file mode 100644
index 000000000000..f508858d1562
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-add-06.ll
@@ -0,0 +1,64 @@
+; Test 64-bit atomic additions, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check addition of a variable.
+define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f1:
+; CHECK: laag %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw add i64 *%src, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check addition of 1, which needs a temporary.
+define i64 @f2(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lghi [[TMP:%r[0-5]]], 1
+; CHECK: laag %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw add i64 *%src, i64 1 seq_cst
+ ret i64 %res
+}
+
+; Check the high end of the LAAG range.
+define i64 @f3(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f3:
+; CHECK: laag %r2, %r4, 524280(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65535
+ %res = atomicrmw add i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword up, which needs separate address logic.
+define i64 @f4(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: laag %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65536
+ %res = atomicrmw add i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the low end of the LAAG range.
+define i64 @f5(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f5:
+; CHECK: laag %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65536
+ %res = atomicrmw add i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword down, which needs separate address logic.
+define i64 @f6(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524296
+; CHECK: laag %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65537
+ %res = atomicrmw add i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-and-05.ll b/test/CodeGen/SystemZ/atomicrmw-and-05.ll
new file mode 100644
index 000000000000..f0b999c60431
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-and-05.ll
@@ -0,0 +1,64 @@
+; Test 32-bit atomic ANDs, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check AND of a variable.
+define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f1:
+; CHECK: lan %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw and i32 *%src, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check AND of 1, which needs a temporary.
+define i32 @f2(i32 %dummy, i32 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lhi [[TMP:%r[0-5]]], 1
+; CHECK: lan %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw and i32 *%src, i32 1 seq_cst
+ ret i32 %res
+}
+
+; Check the high end of the LAN range.
+define i32 @f3(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f3:
+; CHECK: lan %r2, %r4, 524284(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131071
+ %res = atomicrmw and i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word up, which needs separate address logic.
+define i32 @f4(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: lan %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131072
+ %res = atomicrmw and i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the low end of the LAN range.
+define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f5:
+; CHECK: lan %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131072
+ %res = atomicrmw and i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word down, which needs separate address logic.
+define i32 @f6(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524292
+; CHECK: lan %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131073
+ %res = atomicrmw and i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-and-06.ll b/test/CodeGen/SystemZ/atomicrmw-and-06.ll
new file mode 100644
index 000000000000..e5b71945d57c
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-and-06.ll
@@ -0,0 +1,64 @@
+; Test 64-bit atomic ANDs, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check AND of a variable.
+define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f1:
+; CHECK: lang %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw and i64 *%src, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check AND of -2, which needs a temporary.
+define i64 @f2(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lghi [[TMP:%r[0-5]]], -2
+; CHECK: lang %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw and i64 *%src, i64 -2 seq_cst
+ ret i64 %res
+}
+
+; Check the high end of the LANG range.
+define i64 @f3(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f3:
+; CHECK: lang %r2, %r4, 524280(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65535
+ %res = atomicrmw and i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword up, which needs separate address logic.
+define i64 @f4(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: lang %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65536
+ %res = atomicrmw and i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the low end of the LANG range.
+define i64 @f5(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f5:
+; CHECK: lang %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65536
+ %res = atomicrmw and i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword down, which needs separate address logic.
+define i64 @f6(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524296
+; CHECK: lang %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65537
+ %res = atomicrmw and i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-or-05.ll b/test/CodeGen/SystemZ/atomicrmw-or-05.ll
new file mode 100644
index 000000000000..b38654ca6f07
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-or-05.ll
@@ -0,0 +1,64 @@
+; Test 32-bit atomic ORs, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check OR of a variable.
+define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f1:
+; CHECK: lao %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw or i32 *%src, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check OR of 1, which needs a temporary.
+define i32 @f2(i32 %dummy, i32 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lhi [[TMP:%r[0-5]]], 1
+; CHECK: lao %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw or i32 *%src, i32 1 seq_cst
+ ret i32 %res
+}
+
+; Check the high end of the LAO range.
+define i32 @f3(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f3:
+; CHECK: lao %r2, %r4, 524284(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131071
+ %res = atomicrmw or i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word up, which needs separate address logic.
+define i32 @f4(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: lao %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131072
+ %res = atomicrmw or i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the low end of the LAO range.
+define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f5:
+; CHECK: lao %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131072
+ %res = atomicrmw or i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word down, which needs separate address logic.
+define i32 @f6(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524292
+; CHECK: lao %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131073
+ %res = atomicrmw or i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-or-06.ll b/test/CodeGen/SystemZ/atomicrmw-or-06.ll
new file mode 100644
index 000000000000..30874abfe4a2
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-or-06.ll
@@ -0,0 +1,64 @@
+; Test 64-bit atomic ORs, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check OR of a variable.
+define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f1:
+; CHECK: laog %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw or i64 *%src, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check OR of 1, which needs a temporary.
+define i64 @f2(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lghi [[TMP:%r[0-5]]], 1
+; CHECK: laog %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw or i64 *%src, i64 1 seq_cst
+ ret i64 %res
+}
+
+; Check the high end of the LAOG range.
+define i64 @f3(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f3:
+; CHECK: laog %r2, %r4, 524280(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65535
+ %res = atomicrmw or i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword up, which needs separate address logic.
+define i64 @f4(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: laog %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65536
+ %res = atomicrmw or i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the low end of the LAOG range.
+define i64 @f5(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f5:
+; CHECK: laog %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65536
+ %res = atomicrmw or i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword down, which needs separate address logic.
+define i64 @f6(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524296
+; CHECK: laog %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65537
+ %res = atomicrmw or i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-sub-05.ll b/test/CodeGen/SystemZ/atomicrmw-sub-05.ll
new file mode 100644
index 000000000000..7668f0e2a7ac
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-sub-05.ll
@@ -0,0 +1,69 @@
+; Test 32-bit atomic subtractions, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check addition of a variable.
+define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f1:
+; CHECK: lcr [[NEG:%r[0-5]]], %r4
+; CHECK: laa %r2, [[NEG]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw sub i32 *%src, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check addition of 1, which needs a temporary.
+define i32 @f2(i32 %dummy, i32 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lhi [[TMP:%r[0-5]]], -1
+; CHECK: laa %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw sub i32 *%src, i32 1 seq_cst
+ ret i32 %res
+}
+
+; Check the high end of the LAA range.
+define i32 @f3(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f3:
+; CHECK: lcr [[NEG:%r[0-5]]], %r4
+; CHECK: laa %r2, [[NEG]], 524284(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131071
+ %res = atomicrmw sub i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word up, which needs separate address logic.
+define i32 @f4(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f4:
+; CHECK-DAG: lcr [[NEG:%r[0-5]]], %r4
+; CHECK-DAG: agfi %r3, 524288
+; CHECK: laa %r2, [[NEG]], 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131072
+ %res = atomicrmw sub i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the low end of the LAA range.
+define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f5:
+; CHECK: lcr [[NEG:%r[0-5]]], %r4
+; CHECK: laa %r2, [[NEG]], -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131072
+ %res = atomicrmw sub i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word down, which needs separate address logic.
+define i32 @f6(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f6:
+; CHECK-DAG: lcr [[NEG:%r[0-5]]], %r4
+; CHECK-DAG: agfi %r3, -524292
+; CHECK: laa %r2, [[NEG]], 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131073
+ %res = atomicrmw sub i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-sub-06.ll b/test/CodeGen/SystemZ/atomicrmw-sub-06.ll
new file mode 100644
index 000000000000..5d11bdf96cde
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-sub-06.ll
@@ -0,0 +1,69 @@
+; Test 64-bit atomic subtractions, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check addition of a variable.
+define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f1:
+; CHECK: lcgr [[NEG:%r[0-5]]], %r4
+; CHECK: laag %r2, [[NEG]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw sub i64 *%src, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check addition of 1, which needs a temporary.
+define i64 @f2(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lghi [[TMP:%r[0-5]]], -1
+; CHECK: laag %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw sub i64 *%src, i64 1 seq_cst
+ ret i64 %res
+}
+
+; Check the high end of the LAAG range.
+define i64 @f3(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f3:
+; CHECK: lcgr [[NEG:%r[0-5]]], %r4
+; CHECK: laag %r2, [[NEG]], 524280(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65535
+ %res = atomicrmw sub i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword up, which needs separate address logic.
+define i64 @f4(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f4:
+; CHECK-DAG: lcgr [[NEG:%r[0-5]]], %r4
+; CHECK-DAG: agfi %r3, 524288
+; CHECK: laag %r2, [[NEG]], 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65536
+ %res = atomicrmw sub i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the low end of the LAAG range.
+define i64 @f5(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f5:
+; CHECK: lcgr [[NEG:%r[0-5]]], %r4
+; CHECK: laag %r2, [[NEG]], -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65536
+ %res = atomicrmw sub i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword down, which needs separate address logic.
+define i64 @f6(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f6:
+; CHECK-DAG: lcgr [[NEG:%r[0-5]]], %r4
+; CHECK-DAG: agfi %r3, -524296
+; CHECK: laag %r2, [[NEG]], 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65537
+ %res = atomicrmw sub i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-xor-05.ll b/test/CodeGen/SystemZ/atomicrmw-xor-05.ll
new file mode 100644
index 000000000000..e9e7d30b3578
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-xor-05.ll
@@ -0,0 +1,64 @@
+; Test 32-bit atomic ORs, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check OR of a variable.
+define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f1:
+; CHECK: lax %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw xor i32 *%src, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check OR of 1, which needs a temporary.
+define i32 @f2(i32 %dummy, i32 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lhi [[TMP:%r[0-5]]], 1
+; CHECK: lax %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw xor i32 *%src, i32 1 seq_cst
+ ret i32 %res
+}
+
+; Check the high end of the LAX range.
+define i32 @f3(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f3:
+; CHECK: lax %r2, %r4, 524284(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131071
+ %res = atomicrmw xor i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word up, which needs separate address logic.
+define i32 @f4(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: lax %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 131072
+ %res = atomicrmw xor i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the low end of the LAX range.
+define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f5:
+; CHECK: lax %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131072
+ %res = atomicrmw xor i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
+
+; Check the next word down, which needs separate address logic.
+define i32 @f6(i32 %dummy, i32 *%src, i32 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524292
+; CHECK: lax %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i32 *%src, i32 -131073
+ %res = atomicrmw xor i32 *%ptr, i32 %b seq_cst
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/atomicrmw-xor-06.ll b/test/CodeGen/SystemZ/atomicrmw-xor-06.ll
new file mode 100644
index 000000000000..0870c6476f61
--- /dev/null
+++ b/test/CodeGen/SystemZ/atomicrmw-xor-06.ll
@@ -0,0 +1,64 @@
+; Test 64-bit atomic XORs, z196 version.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check XOR of a variable.
+define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f1:
+; CHECK: laxg %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw xor i64 *%src, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check XOR of 1, which needs a temporary.
+define i64 @f2(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lghi [[TMP:%r[0-5]]], 1
+; CHECK: laxg %r2, [[TMP]], 0(%r3)
+; CHECK: br %r14
+ %res = atomicrmw xor i64 *%src, i64 1 seq_cst
+ ret i64 %res
+}
+
+; Check the high end of the LAXG range.
+define i64 @f3(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f3:
+; CHECK: laxg %r2, %r4, 524280(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65535
+ %res = atomicrmw xor i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword up, which needs separate address logic.
+define i64 @f4(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r3, 524288
+; CHECK: laxg %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 65536
+ %res = atomicrmw xor i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the low end of the LAXG range.
+define i64 @f5(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f5:
+; CHECK: laxg %r2, %r4, -524288(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65536
+ %res = atomicrmw xor i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
+
+; Check the next doubleword down, which needs separate address logic.
+define i64 @f6(i64 %dummy, i64 *%src, i64 %b) {
+; CHECK-LABEL: f6:
+; CHECK: agfi %r3, -524296
+; CHECK: laxg %r2, %r4, 0(%r3)
+; CHECK: br %r14
+ %ptr = getelementptr i64 *%src, i64 -65537
+ %res = atomicrmw xor i64 *%ptr, i64 %b seq_cst
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/cmpxchg-01.ll b/test/CodeGen/SystemZ/cmpxchg-01.ll
index d5ea97786900..5118aadcf2ad 100644
--- a/test/CodeGen/SystemZ/cmpxchg-01.ll
+++ b/test/CodeGen/SystemZ/cmpxchg-01.ll
@@ -32,7 +32,8 @@ define i8 @f1(i8 %dummy, i8 *%src, i8 %cmp, i8 %swap) {
; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
; CHECK-SHIFT: rll
; CHECK-SHIFT: rll {{%r[0-9]+}}, %r5, -8([[NEGSHIFT]])
- %res = cmpxchg i8 *%src, i8 %cmp, i8 %swap seq_cst
+ %pair = cmpxchg i8 *%src, i8 %cmp, i8 %swap seq_cst seq_cst
+ %res = extractvalue { i8, i1 } %pair, 0
ret i8 %res
}
@@ -50,6 +51,7 @@ define i8 @f2(i8 *%src) {
; CHECK-SHIFT: risbg
; CHECK-SHIFT: risbg [[SWAP]], {{%r[0-9]+}}, 32, 55, 0
; CHECK-SHIFT: br %r14
- %res = cmpxchg i8 *%src, i8 42, i8 88 seq_cst
+ %pair = cmpxchg i8 *%src, i8 42, i8 88 seq_cst seq_cst
+ %res = extractvalue { i8, i1 } %pair, 0
ret i8 %res
}
diff --git a/test/CodeGen/SystemZ/cmpxchg-02.ll b/test/CodeGen/SystemZ/cmpxchg-02.ll
index 08c79d717c1e..9eb0628b5a30 100644
--- a/test/CodeGen/SystemZ/cmpxchg-02.ll
+++ b/test/CodeGen/SystemZ/cmpxchg-02.ll
@@ -32,7 +32,8 @@ define i16 @f1(i16 %dummy, i16 *%src, i16 %cmp, i16 %swap) {
; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
; CHECK-SHIFT: rll
; CHECK-SHIFT: rll {{%r[0-9]+}}, %r5, -16([[NEGSHIFT]])
- %res = cmpxchg i16 *%src, i16 %cmp, i16 %swap seq_cst
+ %pair = cmpxchg i16 *%src, i16 %cmp, i16 %swap seq_cst seq_cst
+ %res = extractvalue { i16, i1 } %pair, 0
ret i16 %res
}
@@ -50,6 +51,7 @@ define i16 @f2(i16 *%src) {
; CHECK-SHIFT: risbg
; CHECK-SHIFT: risbg [[SWAP]], {{%r[0-9]+}}, 32, 47, 0
; CHECK-SHIFT: br %r14
- %res = cmpxchg i16 *%src, i16 42, i16 88 seq_cst
+ %pair = cmpxchg i16 *%src, i16 42, i16 88 seq_cst seq_cst
+ %res = extractvalue { i16, i1 } %pair, 0
ret i16 %res
}
diff --git a/test/CodeGen/SystemZ/cmpxchg-03.ll b/test/CodeGen/SystemZ/cmpxchg-03.ll
index 3917979ac24c..c5fab4dc0439 100644
--- a/test/CodeGen/SystemZ/cmpxchg-03.ll
+++ b/test/CodeGen/SystemZ/cmpxchg-03.ll
@@ -7,7 +7,8 @@ define i32 @f1(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK-LABEL: f1:
; CHECK: cs %r2, %r3, 0(%r4)
; CHECK: br %r14
- %val = cmpxchg i32 *%src, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%src, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -17,7 +18,8 @@ define i32 @f2(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: cs %r2, %r3, 4092(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 1023
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -27,7 +29,8 @@ define i32 @f3(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: csy %r2, %r3, 4096(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 1024
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -37,7 +40,8 @@ define i32 @f4(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: csy %r2, %r3, 524284(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 131071
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -49,7 +53,8 @@ define i32 @f5(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: cs %r2, %r3, 0(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 131072
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -59,7 +64,8 @@ define i32 @f6(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: csy %r2, %r3, -4(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 -1
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -69,7 +75,8 @@ define i32 @f7(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: csy %r2, %r3, -524288(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 -131072
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -81,7 +88,8 @@ define i32 @f8(i32 %cmp, i32 %swap, i32 *%src) {
; CHECK: cs %r2, %r3, 0(%r4)
; CHECK: br %r14
%ptr = getelementptr i32 *%src, i64 -131073
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -93,7 +101,8 @@ define i32 @f9(i32 %cmp, i32 %swap, i64 %src, i64 %index) {
; CHECK: br %r14
%add1 = add i64 %src, %index
%ptr = inttoptr i64 %add1 to i32 *
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -106,7 +115,8 @@ define i32 @f10(i32 %cmp, i32 %swap, i64 %src, i64 %index) {
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 4096
%ptr = inttoptr i64 %add2 to i32 *
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -116,7 +126,8 @@ define i32 @f11(i32 %dummy, i32 %swap, i32 *%ptr) {
; CHECK: lhi %r2, 1001
; CHECK: cs %r2, %r3, 0(%r4)
; CHECK: br %r14
- %val = cmpxchg i32 *%ptr, i32 1001, i32 %swap seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 1001, i32 %swap seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
@@ -126,6 +137,7 @@ define i32 @f12(i32 %cmp, i32 *%ptr) {
; CHECK: lhi [[SWAP:%r[0-9]+]], 1002
; CHECK: cs %r2, [[SWAP]], 0(%r3)
; CHECK: br %r14
- %val = cmpxchg i32 *%ptr, i32 %cmp, i32 1002 seq_cst
+ %pair = cmpxchg i32 *%ptr, i32 %cmp, i32 1002 seq_cst seq_cst
+ %val = extractvalue { i32, i1 } %pair, 0
ret i32 %val
}
diff --git a/test/CodeGen/SystemZ/cmpxchg-04.ll b/test/CodeGen/SystemZ/cmpxchg-04.ll
index f58868f04f2d..ba1493e1853e 100644
--- a/test/CodeGen/SystemZ/cmpxchg-04.ll
+++ b/test/CodeGen/SystemZ/cmpxchg-04.ll
@@ -7,7 +7,8 @@ define i64 @f1(i64 %cmp, i64 %swap, i64 *%src) {
; CHECK-LABEL: f1:
; CHECK: csg %r2, %r3, 0(%r4)
; CHECK: br %r14
- %val = cmpxchg i64 *%src, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%src, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -17,7 +18,8 @@ define i64 @f2(i64 %cmp, i64 %swap, i64 *%src) {
; CHECK: csg %r2, %r3, 524280(%r4)
; CHECK: br %r14
%ptr = getelementptr i64 *%src, i64 65535
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -29,7 +31,8 @@ define i64 @f3(i64 %cmp, i64 %swap, i64 *%src) {
; CHECK: csg %r2, %r3, 0(%r4)
; CHECK: br %r14
%ptr = getelementptr i64 *%src, i64 65536
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -39,7 +42,8 @@ define i64 @f4(i64 %cmp, i64 %swap, i64 *%src) {
; CHECK: csg %r2, %r3, -8(%r4)
; CHECK: br %r14
%ptr = getelementptr i64 *%src, i64 -1
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -49,7 +53,8 @@ define i64 @f5(i64 %cmp, i64 %swap, i64 *%src) {
; CHECK: csg %r2, %r3, -524288(%r4)
; CHECK: br %r14
%ptr = getelementptr i64 *%src, i64 -65536
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -61,7 +66,8 @@ define i64 @f6(i64 %cmp, i64 %swap, i64 *%src) {
; CHECK: csg %r2, %r3, 0(%r4)
; CHECK: br %r14
%ptr = getelementptr i64 *%src, i64 -65537
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -73,7 +79,8 @@ define i64 @f7(i64 %cmp, i64 %swap, i64 %src, i64 %index) {
; CHECK: br %r14
%add1 = add i64 %src, %index
%ptr = inttoptr i64 %add1 to i64 *
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -83,7 +90,8 @@ define i64 @f8(i64 %dummy, i64 %swap, i64 *%ptr) {
; CHECK: lghi %r2, 1001
; CHECK: csg %r2, %r3, 0(%r4)
; CHECK: br %r14
- %val = cmpxchg i64 *%ptr, i64 1001, i64 %swap seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 1001, i64 %swap seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
@@ -93,6 +101,7 @@ define i64 @f9(i64 %cmp, i64 *%ptr) {
; CHECK: lghi [[SWAP:%r[0-9]+]], 1002
; CHECK: csg %r2, [[SWAP]], 0(%r3)
; CHECK: br %r14
- %val = cmpxchg i64 *%ptr, i64 %cmp, i64 1002 seq_cst
+ %pairval = cmpxchg i64 *%ptr, i64 %cmp, i64 1002 seq_cst seq_cst
+ %val = extractvalue { i64, i1 } %pairval, 0
ret i64 %val
}
diff --git a/test/CodeGen/SystemZ/cond-store-01.ll b/test/CodeGen/SystemZ/cond-store-01.ll
index d55ea2133e8f..62e9796fa21b 100644
--- a/test/CodeGen/SystemZ/cond-store-01.ll
+++ b/test/CodeGen/SystemZ/cond-store-01.ll
@@ -347,11 +347,10 @@ define void @f19(i8 *%ptr, i8 %alt, i32 %limit) {
define void @f20(i8 *%ptr, i8 %alt, i32 %limit) {
; FIXME: should use a normal load instead of CS.
; CHECK-LABEL: f20:
-; CHECK: cs {{%r[0-9]+}},
-; CHECK: jl
+; CHECK: lb {{%r[0-9]+}}, 0(%r2)
; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
; CHECK: [[LABEL]]:
-; CHECK: stc {{%r[0-9]+}},
+; CHECK: stc {{%r[0-9]+}}, 0(%r2)
; CHECK: br %r14
%cond = icmp ult i32 %limit, 420
%orig = load atomic i8 *%ptr unordered, align 1
@@ -367,7 +366,7 @@ define void @f21(i8 *%ptr, i8 %alt, i32 %limit) {
; CHECK: jhe [[LABEL:[^ ]*]]
; CHECK: lb %r3, 0(%r2)
; CHECK: [[LABEL]]:
-; CHECK: cs {{%r[0-9]+}},
+; CHECK: stc %r3, 0(%r2)
; CHECK: br %r14
%cond = icmp ult i32 %limit, 420
%orig = load i8 *%ptr
diff --git a/test/CodeGen/SystemZ/cond-store-02.ll b/test/CodeGen/SystemZ/cond-store-02.ll
index 91bc4860b384..4fbcdaba5103 100644
--- a/test/CodeGen/SystemZ/cond-store-02.ll
+++ b/test/CodeGen/SystemZ/cond-store-02.ll
@@ -347,11 +347,10 @@ define void @f19(i16 *%ptr, i16 %alt, i32 %limit) {
define void @f20(i16 *%ptr, i16 %alt, i32 %limit) {
; FIXME: should use a normal load instead of CS.
; CHECK-LABEL: f20:
-; CHECK: cs {{%r[0-9]+}},
-; CHECK: jl
+; CHECK: lh {{%r[0-9]+}}, 0(%r2)
; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
; CHECK: [[LABEL]]:
-; CHECK: sth {{%r[0-9]+}},
+; CHECK: sth {{%r[0-9]+}}, 0(%r2)
; CHECK: br %r14
%cond = icmp ult i32 %limit, 420
%orig = load atomic i16 *%ptr unordered, align 2
@@ -367,7 +366,7 @@ define void @f21(i16 *%ptr, i16 %alt, i32 %limit) {
; CHECK: jhe [[LABEL:[^ ]*]]
; CHECK: lh %r3, 0(%r2)
; CHECK: [[LABEL]]:
-; CHECK: cs {{%r[0-9]+}},
+; CHECK: sth %r3, 0(%r2)
; CHECK: br %r14
%cond = icmp ult i32 %limit, 420
%orig = load i16 *%ptr
diff --git a/test/CodeGen/SystemZ/cond-store-03.ll b/test/CodeGen/SystemZ/cond-store-03.ll
index d4fd48d61324..4b22555d0d60 100644
--- a/test/CodeGen/SystemZ/cond-store-03.ll
+++ b/test/CodeGen/SystemZ/cond-store-03.ll
@@ -272,7 +272,7 @@ define void @f15(i32 *%ptr, i32 %alt, i32 %limit) {
define void @f16(i32 *%ptr, i32 %alt, i32 %limit) {
; FIXME: should use a normal load instead of CS.
; CHECK-LABEL: f16:
-; CHECK: cs {{%r[0-5]}}, {{%r[0-5]}}, 0(%r2)
+; CHECK: l {{%r[0-5]}}, 0(%r2)
; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
; CHECK: [[LABEL]]:
; CHECK: st {{%r[0-5]}}, 0(%r2)
@@ -291,7 +291,7 @@ define void @f17(i32 *%ptr, i32 %alt, i32 %limit) {
; CHECK: jhe [[LABEL:[^ ]*]]
; CHECK: l %r3, 0(%r2)
; CHECK: [[LABEL]]:
-; CHECK: cs {{%r[0-5]}}, %r3, 0(%r2)
+; CHECK: st %r3, 0(%r2)
; CHECK: br %r14
%cond = icmp ult i32 %limit, 420
%orig = load i32 *%ptr
diff --git a/test/CodeGen/SystemZ/cond-store-04.ll b/test/CodeGen/SystemZ/cond-store-04.ll
index fc565c432fff..346b51a17d78 100644
--- a/test/CodeGen/SystemZ/cond-store-04.ll
+++ b/test/CodeGen/SystemZ/cond-store-04.ll
@@ -164,7 +164,7 @@ define void @f9(i64 *%ptr, i64 %alt, i32 %limit) {
define void @f10(i64 *%ptr, i64 %alt, i32 %limit) {
; FIXME: should use a normal load instead of CSG.
; CHECK-LABEL: f10:
-; CHECK: csg {{%r[0-5]}}, {{%r[0-5]}}, 0(%r2)
+; CHECK: lg {{%r[0-5]}}, 0(%r2)
; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
; CHECK: [[LABEL]]:
; CHECK: stg {{%r[0-5]}}, 0(%r2)
@@ -183,7 +183,7 @@ define void @f11(i64 *%ptr, i64 %alt, i32 %limit) {
; CHECK: jhe [[LABEL:[^ ]*]]
; CHECK: lg %r3, 0(%r2)
; CHECK: [[LABEL]]:
-; CHECK: csg {{%r[0-5]}}, %r3, 0(%r2)
+; CHECK: stg %r3, 0(%r2)
; CHECK: br %r14
%cond = icmp ult i32 %limit, 420
%orig = load i64 *%ptr
diff --git a/test/CodeGen/SystemZ/fp-cmp-04.ll b/test/CodeGen/SystemZ/fp-cmp-04.ll
index 8d842164fa4f..781a3beb4d4d 100644
--- a/test/CodeGen/SystemZ/fp-cmp-04.ll
+++ b/test/CodeGen/SystemZ/fp-cmp-04.ll
@@ -1,4 +1,4 @@
-; Test that floating-point compares are ommitted if CC already has the
+; Test that floating-point compares are omitted if CC already has the
; right value.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
@@ -346,3 +346,62 @@ store:
exit:
ret double %val
}
+
+; Repeat f2 with a comparison against -0.
+define float @f17(float %a, float %b, float *%dest) {
+; CHECK-LABEL: f17:
+; CHECK: aebr %f0, %f2
+; CHECK-NEXT: jl .L{{.*}}
+; CHECK: br %r14
+entry:
+ %res = fadd float %a, %b
+ %cmp = fcmp olt float %res, -0.0
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store float %b, float *%dest
+ br label %exit
+
+exit:
+ ret float %res
+}
+
+; Test another form of f7 in which the condition is based on the unnegated
+; result. This is what InstCombine would produce.
+define float @f18(float %dummy, float %a, float *%dest) {
+; CHECK-LABEL: f18:
+; CHECK: lnebr %f0, %f2
+; CHECK-NEXT: jl .L{{.*}}
+; CHECK: br %r14
+entry:
+ %abs = call float @llvm.fabs.f32(float %a)
+ %res = fsub float -0.0, %abs
+ %cmp = fcmp ogt float %abs, 0.0
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store float %res, float *%dest
+ br label %exit
+
+exit:
+ ret float %res
+}
+
+; Similarly for f8.
+define float @f19(float %dummy, float %a, float *%dest) {
+; CHECK-LABEL: f19:
+; CHECK: lcebr %f0, %f2
+; CHECK-NEXT: jle .L{{.*}}
+; CHECK: br %r14
+entry:
+ %res = fsub float -0.0, %a
+ %cmp = fcmp oge float %a, 0.0
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store float %res, float *%dest
+ br label %exit
+
+exit:
+ ret float %res
+}
diff --git a/test/CodeGen/SystemZ/fp-conv-06.ll b/test/CodeGen/SystemZ/fp-conv-06.ll
index 466c1456a0cb..8a3971a9929c 100644
--- a/test/CodeGen/SystemZ/fp-conv-06.ll
+++ b/test/CodeGen/SystemZ/fp-conv-06.ll
@@ -1,6 +1,6 @@
-; Test conversions of unsigned i32s to floating-point values.
+; Test conversions of unsigned i32s to floating-point values (z10 only).
;
-; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; Check i32->f32. There is no native instruction, so we must promote
; to i64 first.
diff --git a/test/CodeGen/SystemZ/fp-conv-08.ll b/test/CodeGen/SystemZ/fp-conv-08.ll
index 69b2d13e29f0..295ce8bdbe2c 100644
--- a/test/CodeGen/SystemZ/fp-conv-08.ll
+++ b/test/CodeGen/SystemZ/fp-conv-08.ll
@@ -1,6 +1,6 @@
-; Test conversions of unsigned i64s to floating-point values.
+; Test conversions of unsigned i64s to floating-point values (z10 only).
;
-; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; Test i64->f32. There's no native support for unsigned i64-to-fp conversions,
; but we should be able to implement them using signed i64-to-fp conversions.
diff --git a/test/CodeGen/SystemZ/fp-conv-10.ll b/test/CodeGen/SystemZ/fp-conv-10.ll
index 723d19d2a1de..b8155ed067da 100644
--- a/test/CodeGen/SystemZ/fp-conv-10.ll
+++ b/test/CodeGen/SystemZ/fp-conv-10.ll
@@ -1,6 +1,6 @@
-; Test conversion of floating-point values to unsigned i32s.
+; Test conversion of floating-point values to unsigned i32s (z10 only).
;
-; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; z10 doesn't have native support for unsigned fp-to-i32 conversions;
; they were added in z196 as the Convert to Logical family of instructions.
diff --git a/test/CodeGen/SystemZ/fp-conv-12.ll b/test/CodeGen/SystemZ/fp-conv-12.ll
index 6cc343abdafc..770c9407a0af 100644
--- a/test/CodeGen/SystemZ/fp-conv-12.ll
+++ b/test/CodeGen/SystemZ/fp-conv-12.ll
@@ -1,6 +1,6 @@
-; Test conversion of floating-point values to unsigned i64s.
+; Test conversion of floating-point values to unsigned i64s (z10 only).
;
-; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; z10 doesn't have native support for unsigned fp-to-i64 conversions;
; they were added in z196 as the Convert to Logical family of instructions.
diff --git a/test/CodeGen/SystemZ/fp-conv-13.ll b/test/CodeGen/SystemZ/fp-conv-13.ll
new file mode 100644
index 000000000000..96293bc8d270
--- /dev/null
+++ b/test/CodeGen/SystemZ/fp-conv-13.ll
@@ -0,0 +1,64 @@
+; Test conversions of unsigned integers to floating-point values
+; (z196 and above).
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check i32->f32.
+define float @f1(i32 %i) {
+; CHECK-LABEL: f1:
+; CHECK: celfbr %f0, 0, %r2, 0
+; CHECK: br %r14
+ %conv = uitofp i32 %i to float
+ ret float %conv
+}
+
+; Check i32->f64.
+define double @f2(i32 %i) {
+; CHECK-LABEL: f2:
+; CHECK: cdlfbr %f0, 0, %r2, 0
+; CHECK: br %r14
+ %conv = uitofp i32 %i to double
+ ret double %conv
+}
+
+; Check i32->f128.
+define void @f3(i32 %i, fp128 *%dst) {
+; CHECK-LABEL: f3:
+; CHECK: cxlfbr %f0, 0, %r2, 0
+; CHECK-DAG: std %f0, 0(%r3)
+; CHECK-DAG: std %f2, 8(%r3)
+; CHECK: br %r14
+ %conv = uitofp i32 %i to fp128
+ store fp128 %conv, fp128 *%dst
+ ret void
+}
+
+; Check i64->f32.
+define float @f4(i64 %i) {
+; CHECK-LABEL: f4:
+; CHECK: celgbr %f0, 0, %r2, 0
+; CHECK: br %r14
+ %conv = uitofp i64 %i to float
+ ret float %conv
+}
+
+; Check i64->f64.
+define double @f5(i64 %i) {
+; CHECK-LABEL: f5:
+; CHECK: cdlgbr %f0, 0, %r2, 0
+; CHECK: br %r14
+ %conv = uitofp i64 %i to double
+ ret double %conv
+}
+
+; Check i64->f128.
+define void @f6(i64 %i, fp128 *%dst) {
+; CHECK-LABEL: f6:
+; CHECK: cxlgbr %f0, 0, %r2, 0
+; CHECK-DAG: std %f0, 0(%r3)
+; CHECK-DAG: std %f2, 8(%r3)
+; CHECK: br %r14
+ %conv = uitofp i64 %i to fp128
+ store fp128 %conv, fp128 *%dst
+ ret void
+}
diff --git a/test/CodeGen/SystemZ/fp-conv-14.ll b/test/CodeGen/SystemZ/fp-conv-14.ll
new file mode 100644
index 000000000000..e926e9bb31f5
--- /dev/null
+++ b/test/CodeGen/SystemZ/fp-conv-14.ll
@@ -0,0 +1,63 @@
+; Test conversion of floating-point values to unsigned integers.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Test f32->i32.
+define i32 @f1(float %f) {
+; CHECK-LABEL: f1:
+; CHECK: clfebr %r2, 5, %f0, 0
+; CHECK: br %r14
+ %conv = fptoui float %f to i32
+ ret i32 %conv
+}
+
+; Test f64->i32.
+define i32 @f2(double %f) {
+; CHECK-LABEL: f2:
+; CHECK: clfdbr %r2, 5, %f0, 0
+; CHECK: br %r14
+ %conv = fptoui double %f to i32
+ ret i32 %conv
+}
+
+; Test f128->i32.
+define i32 @f3(fp128 *%src) {
+; CHECK-LABEL: f3:
+; CHECK-DAG: ld %f0, 0(%r2)
+; CHECK-DAG: ld %f2, 8(%r2)
+; CHECK: clfxbr %r2, 5, %f0, 0
+; CHECK: br %r14
+ %f = load fp128 *%src
+ %conv = fptoui fp128 %f to i32
+ ret i32 %conv
+}
+
+; Test f32->i64.
+define i64 @f4(float %f) {
+; CHECK-LABEL: f4:
+; CHECK: clgebr %r2, 5, %f0, 0
+; CHECK: br %r14
+ %conv = fptoui float %f to i64
+ ret i64 %conv
+}
+
+; Test f64->i64.
+define i64 @f5(double %f) {
+; CHECK-LABEL: f5:
+; CHECK: clgdbr %r2, 5, %f0, 0
+; CHECK: br %r14
+ %conv = fptoui double %f to i64
+ ret i64 %conv
+}
+
+; Test f128->i64.
+define i64 @f6(fp128 *%src) {
+; CHECK-LABEL: f6:
+; CHECK-DAG: ld %f0, 0(%r2)
+; CHECK-DAG: ld %f2, 8(%r2)
+; CHECK: clgxbr %r2, 5, %f0, 0
+; CHECK: br %r14
+ %f = load fp128 *%src
+ %conv = fptoui fp128 %f to i64
+ ret i64 %conv
+}
diff --git a/test/CodeGen/SystemZ/frame-08.ll b/test/CodeGen/SystemZ/frame-08.ll
index da2a6142fb47..aa4e3f481da4 100644
--- a/test/CodeGen/SystemZ/frame-08.ll
+++ b/test/CodeGen/SystemZ/frame-08.ll
@@ -208,7 +208,7 @@ define void @f4(i32 *%ptr, i64 %x) {
ret void
}
-; This is the largest frame size for which the prepatory increment for
+; This is the largest frame size for which the preparatory increment for
; "lmg %r14, %r15, ..." can be done using AGHI.
define void @f5(i32 *%ptr, i64 %x) {
; CHECK-LABEL: f5:
@@ -242,7 +242,7 @@ define void @f5(i32 *%ptr, i64 %x) {
ret void
}
-; This is the smallest frame size for which the prepatory increment for
+; This is the smallest frame size for which the preparatory increment for
; "lmg %r14, %r15, ..." needs to be done using AGFI.
define void @f6(i32 *%ptr, i64 %x) {
; CHECK-LABEL: f6:
diff --git a/test/CodeGen/SystemZ/frame-11.ll b/test/CodeGen/SystemZ/frame-11.ll
index 5145b4d1c862..575a4335d5da 100644
--- a/test/CodeGen/SystemZ/frame-11.ll
+++ b/test/CodeGen/SystemZ/frame-11.ll
@@ -2,17 +2,24 @@
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+declare i8 *@llvm.stacksave()
declare void @llvm.stackrestore(i8 *)
; we should use a frame pointer and tear down the frame based on %r11
; rather than %r15.
-define void @f1(i8 *%src) {
+define void @f1(i32 %count1, i32 %count2) {
; CHECK-LABEL: f1:
; CHECK: stmg %r11, %r15, 88(%r15)
+; CHECK: aghi %r15, -160
; CHECK: lgr %r11, %r15
-; CHECK: lgr %r15, %r2
-; CHECK: lmg %r11, %r15, 88(%r11)
+; CHECK: lgr %r15, %r{{[0-5]}}
+; CHECK: lmg %r11, %r15, 248(%r11)
; CHECK: br %r14
+ %src = call i8 *@llvm.stacksave()
+ %array1 = alloca i8, i32 %count1
+ store volatile i8 0, i8 *%array1
call void @llvm.stackrestore(i8 *%src)
+ %array2 = alloca i8, i32 %count2
+ store volatile i8 0, i8 *%array2
ret void
}
diff --git a/test/CodeGen/SystemZ/frame-13.ll b/test/CodeGen/SystemZ/frame-13.ll
index 393850fbf617..58dee1da58b5 100644
--- a/test/CodeGen/SystemZ/frame-13.ll
+++ b/test/CodeGen/SystemZ/frame-13.ll
@@ -243,8 +243,8 @@ define void @f10(i32 *%vptr) {
; And again with maximum register pressure. The only spill slots that the
; NOFP case needs are the emergency ones, so the offsets are the same as for f2.
-; However, the FP case uses %r11 as the frame pointer and must therefore
-; spill a second register. This leads to an extra displacement of 8.
+; The FP case needs to spill an extra register and is too dependent on
+; register allocation heuristics for a stable test.
define void @f11(i32 *%vptr) {
; CHECK-NOFP-LABEL: f11:
; CHECK-NOFP: stmg %r6, %r15,
@@ -254,15 +254,6 @@ define void @f11(i32 *%vptr) {
; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)
; CHECK-NOFP: lmg %r6, %r15,
; CHECK-NOFP: br %r14
-;
-; CHECK-FP-LABEL: f11:
-; CHECK-FP: stmg %r6, %r15,
-; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11)
-; CHECK-FP: lay [[REGISTER]], 4096(%r11)
-; CHECK-FP: mvhi 8([[REGISTER]]), 42
-; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11)
-; CHECK-FP: lmg %r6, %r15,
-; CHECK-FP: br %r14
%i0 = load volatile i32 *%vptr
%i1 = load volatile i32 *%vptr
%i3 = load volatile i32 *%vptr
diff --git a/test/CodeGen/SystemZ/frame-14.ll b/test/CodeGen/SystemZ/frame-14.ll
index 3b48179c40b6..24169cf61f00 100644
--- a/test/CodeGen/SystemZ/frame-14.ll
+++ b/test/CodeGen/SystemZ/frame-14.ll
@@ -266,8 +266,8 @@ define void @f10(i32 *%vptr) {
; And again with maximum register pressure. The only spill slots that the
; NOFP case needs are the emergency ones, so the offsets are the same as for f4.
-; However, the FP case uses %r11 as the frame pointer and must therefore
-; spill a second register. This leads to an extra displacement of 8.
+; The FP case needs to spill an extra register and is too dependent on
+; register allocation heuristics for a stable test.
define void @f11(i32 *%vptr) {
; CHECK-NOFP-LABEL: f11:
; CHECK-NOFP: stmg %r6, %r15,
@@ -278,16 +278,6 @@ define void @f11(i32 *%vptr) {
; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)
; CHECK-NOFP: lmg %r6, %r15,
; CHECK-NOFP: br %r14
-;
-; CHECK-FP-LABEL: f11:
-; CHECK-FP: stmg %r6, %r15,
-; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11)
-; CHECK-FP: llilh [[REGISTER]], 8
-; CHECK-FP: agr [[REGISTER]], %r11
-; CHECK-FP: mvi 8([[REGISTER]]), 42
-; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11)
-; CHECK-FP: lmg %r6, %r15,
-; CHECK-FP: br %r14
%i0 = load volatile i32 *%vptr
%i1 = load volatile i32 *%vptr
%i3 = load volatile i32 *%vptr
diff --git a/test/CodeGen/SystemZ/insert-06.ll b/test/CodeGen/SystemZ/insert-06.ll
index edcd0c5dccd2..81a9c8770708 100644
--- a/test/CodeGen/SystemZ/insert-06.ll
+++ b/test/CodeGen/SystemZ/insert-06.ll
@@ -178,3 +178,17 @@ define i64 @f14(i64 %a, i64 %b) {
%ext = sext i1 %res to i64
ret i64 %ext
}
+
+; Check another representation of f8.
+define i64 @f15(i64 %a, i8 *%src) {
+; CHECK-LABEL: f15:
+; CHECK-NOT: {{%r[23]}}
+; CHECK: lb %r2, 0(%r3)
+; CHECK: br %r14
+ %byte = load i8 *%src
+ %b = sext i8 %byte to i64
+ %low = and i64 %b, 4294967295
+ %high = and i64 %a, -4294967296
+ %res = or i64 %high, %low
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/int-abs-01.ll b/test/CodeGen/SystemZ/int-abs-01.ll
index 40fb61192c6e..053c347c0b75 100644
--- a/test/CodeGen/SystemZ/int-abs-01.ll
+++ b/test/CodeGen/SystemZ/int-abs-01.ll
@@ -81,3 +81,67 @@ define i64 @f7(i64 %val) {
%res = select i1 %cmp, i64 %neg, i64 %val
ret i64 %res
}
+
+; Test another form of f6, which is that produced by InstCombine.
+define i64 @f8(i64 %val) {
+; CHECK-LABEL: f8:
+; CHECK: lpgfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp slt i64 %shl, 0
+ %abs = select i1 %cmp, i64 %neg, i64 %ashr
+ ret i64 %abs
+}
+
+; Try again with sle rather than slt.
+define i64 @f9(i64 %val) {
+; CHECK-LABEL: f9:
+; CHECK: lpgfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sle i64 %shl, 0
+ %abs = select i1 %cmp, i64 %neg, i64 %ashr
+ ret i64 %abs
+}
+
+; Repeat f8 with the operands reversed.
+define i64 @f10(i64 %val) {
+; CHECK-LABEL: f10:
+; CHECK: lpgfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sgt i64 %shl, 0
+ %abs = select i1 %cmp, i64 %ashr, i64 %neg
+ ret i64 %abs
+}
+
+; Try again with sge rather than sgt.
+define i64 @f11(i64 %val) {
+; CHECK-LABEL: f11:
+; CHECK: lpgfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sge i64 %shl, 0
+ %abs = select i1 %cmp, i64 %ashr, i64 %neg
+ ret i64 %abs
+}
+
+; Repeat f5 with the comparison on the unextended value.
+define i64 @f12(i32 %val) {
+; CHECK-LABEL: f12:
+; CHECK: lpgfr %r2, %r2
+; CHECK: br %r14
+ %ext = sext i32 %val to i64
+ %cmp = icmp slt i32 %val, 0
+ %neg = sub i64 0, %ext
+ %abs = select i1 %cmp, i64 %neg, i64 %ext
+ ret i64 %abs
+}
diff --git a/test/CodeGen/SystemZ/int-cmp-05.ll b/test/CodeGen/SystemZ/int-cmp-05.ll
index f15b76bb87fe..0be43a3ef1bf 100644
--- a/test/CodeGen/SystemZ/int-cmp-05.ll
+++ b/test/CodeGen/SystemZ/int-cmp-05.ll
@@ -291,9 +291,22 @@ define i64 @f15(i32 *%ptr0) {
ret i64 %sel9
}
-; Check the comparison can be reversed if that allows CGF to be used.
-define double @f16(double %a, double %b, i64 %i2, i32 *%ptr) {
+; Check the comparison can be reversed if that allows CGFR to be used.
+define double @f16(double %a, double %b, i64 %i1, i32 %unext) {
; CHECK-LABEL: f16:
+; CHECK: cgfr %r2, %r3
+; CHECK-NEXT: jh
+; CHECK: ldr %f0, %f2
+; CHECK: br %r14
+ %i2 = sext i32 %unext to i64
+ %cond = icmp slt i64 %i2, %i1
+ %res = select i1 %cond, double %a, double %b
+ ret double %res
+}
+
+; Likewise CGF.
+define double @f17(double %a, double %b, i64 %i2, i32 *%ptr) {
+; CHECK-LABEL: f17:
; CHECK: cgf %r2, 0(%r3)
; CHECK-NEXT: jh {{\.L.*}}
; CHECK: ldr %f0, %f2
diff --git a/test/CodeGen/SystemZ/int-cmp-06.ll b/test/CodeGen/SystemZ/int-cmp-06.ll
index 8ab62e89ec39..82007e221766 100644
--- a/test/CodeGen/SystemZ/int-cmp-06.ll
+++ b/test/CodeGen/SystemZ/int-cmp-06.ll
@@ -341,9 +341,35 @@ define i64 @f19(i32 *%ptr0) {
ret i64 %sel9
}
-; Check the comparison can be reversed if that allows CLGF to be used.
-define double @f20(double %a, double %b, i64 %i2, i32 *%ptr) {
+; Check the comparison can be reversed if that allows CLGFR to be used.
+define double @f20(double %a, double %b, i64 %i1, i32 %unext) {
; CHECK-LABEL: f20:
+; CHECK: clgfr %r2, %r3
+; CHECK-NEXT: jh
+; CHECK: ldr %f0, %f2
+; CHECK: br %r14
+ %i2 = zext i32 %unext to i64
+ %cond = icmp ult i64 %i2, %i1
+ %res = select i1 %cond, double %a, double %b
+ ret double %res
+}
+
+; ...and again with the AND representation.
+define double @f21(double %a, double %b, i64 %i1, i64 %unext) {
+; CHECK-LABEL: f21:
+; CHECK: clgfr %r2, %r3
+; CHECK-NEXT: jh
+; CHECK: ldr %f0, %f2
+; CHECK: br %r14
+ %i2 = and i64 %unext, 4294967295
+ %cond = icmp ult i64 %i2, %i1
+ %res = select i1 %cond, double %a, double %b
+ ret double %res
+}
+
+; Check the comparison can be reversed if that allows CLGF to be used.
+define double @f22(double %a, double %b, i64 %i2, i32 *%ptr) {
+; CHECK-LABEL: f22:
; CHECK: clgf %r2, 0(%r3)
; CHECK-NEXT: jh {{\.L.*}}
; CHECK: ldr %f0, %f2
diff --git a/test/CodeGen/SystemZ/int-cmp-44.ll b/test/CodeGen/SystemZ/int-cmp-44.ll
index ae0133f10860..f065e6421295 100644
--- a/test/CodeGen/SystemZ/int-cmp-44.ll
+++ b/test/CodeGen/SystemZ/int-cmp-44.ll
@@ -1,4 +1,4 @@
-; Test that compares are ommitted if CC already has the right value
+; Test that compares are omitted if CC already has the right value
; (z10 version).
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
@@ -797,3 +797,93 @@ store:
exit:
ret i32 %val
}
+
+; Test f35 for in-register extensions.
+define i64 @f39(i64 %dummy, i64 %a, i64 *%dest) {
+; CHECK-LABEL: f39:
+; CHECK: ltgfr %r2, %r3
+; CHECK-NEXT: #APP
+; CHECK-NEXT: blah %r2
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: jh .L{{.*}}
+; CHECK: br %r14
+entry:
+ %val = trunc i64 %a to i32
+ %ext = sext i32 %val to i64
+ call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
+ %cmp = icmp sgt i64 %ext, 0
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i64 %ext, i64 *%dest
+ br label %exit
+
+exit:
+ ret i64 %ext
+}
+
+; ...and again with what InstCombine would produce for f40.
+define i64 @f40(i64 %dummy, i64 %a, i64 *%dest) {
+; CHECK-LABEL: f40:
+; CHECK: ltgfr %r2, %r3
+; CHECK-NEXT: #APP
+; CHECK-NEXT: blah %r2
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: jh .L{{.*}}
+; CHECK: br %r14
+entry:
+ %shl = shl i64 %a, 32
+ %ext = ashr i64 %shl, 32
+ call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
+ %cmp = icmp sgt i64 %shl, 0
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i64 %ext, i64 *%dest
+ br label %exit
+
+exit:
+ ret i64 %ext
+}
+
+; Try a form of f7 in which the subtraction operands are compared directly.
+define i32 @f41(i32 %a, i32 %b, i32 *%dest) {
+; CHECK-LABEL: f41:
+; CHECK: s %r2, 0(%r4)
+; CHECK-NEXT: jne .L{{.*}}
+; CHECK: br %r14
+entry:
+ %cur = load i32 *%dest
+ %res = sub i32 %a, %cur
+ %cmp = icmp ne i32 %a, %cur
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 %b, i32 *%dest
+ br label %exit
+
+exit:
+ ret i32 %res
+}
+
+; A version of f32 that tests the unextended value.
+define i64 @f42(i64 %base, i64 %index, i64 *%dest) {
+; CHECK-LABEL: f42:
+; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
+; CHECK-NEXT: jh .L{{.*}}
+; CHECK: br %r14
+entry:
+ %add = add i64 %base, %index
+ %ptr = inttoptr i64 %add to i32 *
+ %val = load i32 *%ptr
+ %res = sext i32 %val to i64
+ %cmp = icmp sgt i32 %val, 0
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i64 %res, i64 *%dest
+ br label %exit
+
+exit:
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/int-cmp-45.ll b/test/CodeGen/SystemZ/int-cmp-45.ll
index 753a528e46c9..9c9c49c05df1 100644
--- a/test/CodeGen/SystemZ/int-cmp-45.ll
+++ b/test/CodeGen/SystemZ/int-cmp-45.ll
@@ -1,4 +1,4 @@
-; Test that compares are ommitted if CC already has the right value
+; Test that compares are omitted if CC already has the right value
; (z196 version).
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
diff --git a/test/CodeGen/SystemZ/int-cmp-47.ll b/test/CodeGen/SystemZ/int-cmp-47.ll
index 9ebcbfe525ba..038a25b2a6ed 100644
--- a/test/CodeGen/SystemZ/int-cmp-47.ll
+++ b/test/CodeGen/SystemZ/int-cmp-47.ll
@@ -232,3 +232,112 @@ store:
exit:
ret void
}
+
+; Check a case where TMHH can be used to implement a ult comparison.
+define void @f13(i64 %a) {
+; CHECK-LABEL: f13:
+; CHECK: tmhh %r2, 49152
+; CHECK: jno {{\.L.*}}
+; CHECK: br %r14
+entry:
+ %cmp = icmp ult i64 %a, 13835058055282163712
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 1, i32 *@g
+ br label %exit
+
+exit:
+ ret void
+}
+
+; And again with ule.
+define void @f14(i64 %a) {
+; CHECK-LABEL: f14:
+; CHECK: tmhh %r2, 49152
+; CHECK: jno {{\.L.*}}
+; CHECK: br %r14
+entry:
+ %cmp = icmp ule i64 %a, 13835058055282163711
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 1, i32 *@g
+ br label %exit
+
+exit:
+ ret void
+}
+
+; And again with ugt.
+define void @f15(i64 %a) {
+; CHECK-LABEL: f15:
+; CHECK: tmhh %r2, 49152
+; CHECK: jo {{\.L.*}}
+; CHECK: br %r14
+entry:
+ %cmp = icmp ugt i64 %a, 13835058055282163711
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 1, i32 *@g
+ br label %exit
+
+exit:
+ ret void
+}
+
+; And again with uge.
+define void @f16(i64 %a) {
+; CHECK-LABEL: f16:
+; CHECK: tmhh %r2, 49152
+; CHECK: jo {{\.L.*}}
+; CHECK: br %r14
+entry:
+ %cmp = icmp uge i64 %a, 13835058055282163712
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 1, i32 *@g
+ br label %exit
+
+exit:
+ ret void
+}
+
+; Decrease the constant from f13 to make TMHH invalid.
+define void @f17(i64 %a) {
+; CHECK-LABEL: f17:
+; CHECK-NOT: tmhh
+; CHECK: llihh {{%r[0-5]}}, 49151
+; CHECK-NOT: tmhh
+; CHECK: br %r14
+entry:
+ %cmp = icmp ult i64 %a, 13834776580305453056
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 1, i32 *@g
+ br label %exit
+
+exit:
+ ret void
+}
+
+; Check that we don't use TMHH just to test the top bit.
+define void @f18(i64 %a) {
+; CHECK-LABEL: f18:
+; CHECK-NOT: tmhh
+; CHECK: cgijhe %r2, 0,
+; CHECK: br %r14
+entry:
+ %cmp = icmp ult i64 %a, 9223372036854775808
+ br i1 %cmp, label %exit, label %store
+
+store:
+ store i32 1, i32 *@g
+ br label %exit
+
+exit:
+ ret void
+}
diff --git a/test/CodeGen/SystemZ/int-neg-02.ll b/test/CodeGen/SystemZ/int-neg-02.ll
index e26194c162d4..7f3f6375129a 100644
--- a/test/CodeGen/SystemZ/int-neg-02.ll
+++ b/test/CodeGen/SystemZ/int-neg-02.ll
@@ -89,3 +89,136 @@ define i64 @f7(i64 %val) {
%res = sub i64 0, %abs
ret i64 %res
}
+
+; Test another form of f6, which is that produced by InstCombine.
+define i64 @f8(i64 %val) {
+; CHECK-LABEL: f8:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp slt i64 %shl, 0
+ %abs = select i1 %cmp, i64 %neg, i64 %ashr
+ %res = sub i64 0, %abs
+ ret i64 %res
+}
+
+; Try again with sle rather than slt.
+define i64 @f9(i64 %val) {
+; CHECK-LABEL: f9:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sle i64 %shl, 0
+ %abs = select i1 %cmp, i64 %neg, i64 %ashr
+ %res = sub i64 0, %abs
+ ret i64 %res
+}
+
+; Repeat f8 with the operands reversed.
+define i64 @f10(i64 %val) {
+; CHECK-LABEL: f10:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sgt i64 %shl, 0
+ %abs = select i1 %cmp, i64 %ashr, i64 %neg
+ %res = sub i64 0, %abs
+ ret i64 %res
+}
+
+; Try again with sge rather than sgt.
+define i64 @f11(i64 %val) {
+; CHECK-LABEL: f11:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sge i64 %shl, 0
+ %abs = select i1 %cmp, i64 %ashr, i64 %neg
+ %res = sub i64 0, %abs
+ ret i64 %res
+}
+
+; Repeat f8 with the negation coming from swapped operands.
+define i64 @f12(i64 %val) {
+; CHECK-LABEL: f12:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp slt i64 %shl, 0
+ %negabs = select i1 %cmp, i64 %ashr, i64 %neg
+ ret i64 %negabs
+}
+
+; Likewise f9.
+define i64 @f13(i64 %val) {
+; CHECK-LABEL: f13:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sle i64 %shl, 0
+ %negabs = select i1 %cmp, i64 %ashr, i64 %neg
+ ret i64 %negabs
+}
+
+; Likewise f10.
+define i64 @f14(i64 %val) {
+; CHECK-LABEL: f14:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sgt i64 %shl, 0
+ %negabs = select i1 %cmp, i64 %neg, i64 %ashr
+ ret i64 %negabs
+}
+
+; Likewise f11.
+define i64 @f15(i64 %val) {
+; CHECK-LABEL: f15:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %shl = shl i64 %val, 32
+ %ashr = ashr i64 %shl, 32
+ %neg = sub i64 0, %ashr
+ %cmp = icmp sge i64 %shl, 0
+ %negabs = select i1 %cmp, i64 %neg, i64 %ashr
+ ret i64 %negabs
+}
+
+; Repeat f5 with the comparison on the unextended value.
+define i64 @f16(i32 %val) {
+; CHECK-LABEL: f16:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %ext = sext i32 %val to i64
+ %cmp = icmp slt i32 %val, 0
+ %neg = sub i64 0, %ext
+ %abs = select i1 %cmp, i64 %neg, i64 %ext
+ %res = sub i64 0, %abs
+ ret i64 %res
+}
+
+; And again with the negation coming from swapped operands.
+define i64 @f17(i32 %val) {
+; CHECK-LABEL: f17:
+; CHECK: lngfr %r2, %r2
+; CHECK: br %r14
+ %ext = sext i32 %val to i64
+ %cmp = icmp slt i32 %val, 0
+ %neg = sub i64 0, %ext
+ %abs = select i1 %cmp, i64 %ext, i64 %neg
+ ret i64 %abs
+}
diff --git a/test/CodeGen/SystemZ/lit.local.cfg b/test/CodeGen/SystemZ/lit.local.cfg
index b12af09434be..5c02dd3614a4 100644
--- a/test/CodeGen/SystemZ/lit.local.cfg
+++ b/test/CodeGen/SystemZ/lit.local.cfg
@@ -1,4 +1,3 @@
-targets = set(config.root.targets_to_build.split())
-if not 'SystemZ' in targets:
+if not 'SystemZ' in config.root.targets:
config.unsupported = True
diff --git a/test/CodeGen/SystemZ/mature-mc-support.ll b/test/CodeGen/SystemZ/mature-mc-support.ll
new file mode 100644
index 000000000000..5520f55e1e29
--- /dev/null
+++ b/test/CodeGen/SystemZ/mature-mc-support.ll
@@ -0,0 +1,15 @@
+; Test that inline assembly is parsed by the MC layer when MC support is mature
+; (even when the output is assembly).
+; FIXME: SystemZ doesn't use the integrated assembler by default so we only test
+; that -filetype=obj tries to parse the assembly.
+
+; SKIP: not llc -march=systemz < %s > /dev/null 2> %t1
+; SKIP: FileCheck %s < %t1
+
+; RUN: not llc -march=systemz -filetype=obj < %s > /dev/null 2> %t2
+; RUN: FileCheck %s < %t2
+
+
+module asm " .this_directive_is_very_unlikely_to_exist"
+
+; CHECK: LLVM ERROR: Error parsing inline asm
diff --git a/test/CodeGen/SystemZ/risbg-01.ll b/test/CodeGen/SystemZ/risbg-01.ll
index a4d11fdae5b9..d75e8e4b11a6 100644
--- a/test/CodeGen/SystemZ/risbg-01.ll
+++ b/test/CodeGen/SystemZ/risbg-01.ll
@@ -269,12 +269,12 @@ define i64 @f23(i64 %foo) {
; mask and rotate.
define i32 @f24(i32 %foo) {
; CHECK-LABEL: f24:
-; CHECK: nilf %r2, 14
-; CHECK: rll %r2, %r2, 3
+; CHECK: nilf %r2, 254
+; CHECK: rll %r2, %r2, 29
; CHECK: br %r14
- %and = and i32 %foo, 14
- %parta = shl i32 %and, 3
- %partb = lshr i32 %and, 29
+ %and = and i32 %foo, 254
+ %parta = lshr i32 %and, 3
+ %partb = shl i32 %and, 29
%rotl = or i32 %parta, %partb
ret i32 %rotl
}
@@ -295,7 +295,6 @@ define i64 @f25(i64 %foo) {
; This again needs a separate mask and rotate.
define i32 @f26(i32 %foo) {
; CHECK-LABEL: f26:
-; CHECK: nill %r2, 65487
; CHECK: rll %r2, %r2, 5
; CHECK: br %r14
%and = and i32 %foo, -49
@@ -457,11 +456,22 @@ define i64 @f40(i64 %foo, i64 *%dest) {
ret i64 %and
}
+; Check a case where the result is zero-extended.
+define i64 @f41(i32 %a) {
+; CHECK-LABEL: f41
+; CHECK: risbg %r2, %r2, 36, 191, 62
+; CHECK: br %r14
+ %shl = shl i32 %a, 2
+ %shr = lshr i32 %shl, 4
+ %ext = zext i32 %shr to i64
+ ret i64 %ext
+}
+
; In this case the sign extension is converted to a pair of 32-bit shifts,
; which is then extended to 64 bits. We previously used the wrong bit size
; when testing whether the shifted-in bits of the shift right were significant.
-define i64 @f41(i1 %x) {
-; CHECK-LABEL: f41:
+define i64 @f42(i1 %x) {
+; CHECK-LABEL: f42:
; CHECK: sll %r2, 31
; CHECK: sra %r2, 31
; CHECK: llgcr %r2, %r2
diff --git a/test/CodeGen/SystemZ/rnsbg-01.ll b/test/CodeGen/SystemZ/rnsbg-01.ll
index 666aeb21e8d8..282810a78151 100644
--- a/test/CodeGen/SystemZ/rnsbg-01.ll
+++ b/test/CodeGen/SystemZ/rnsbg-01.ll
@@ -255,3 +255,14 @@ define i64 @f22(i64 %a, i64 %b) {
%and = and i64 %a, %rotlorb
ret i64 %and
}
+
+; Check the handling of zext and AND, which isn't suitable for RNSBG.
+define i64 @f23(i64 %a, i32 %b) {
+; CHECK-LABEL: f23:
+; CHECK-NOT: rnsbg
+; CHECK: br %r14
+ %add = add i32 %b, 1
+ %ext = zext i32 %add to i64
+ %and = and i64 %a, %ext
+ ret i64 %and
+}
diff --git a/test/CodeGen/SystemZ/rosbg-01.ll b/test/CodeGen/SystemZ/rosbg-01.ll
index 0abacccba14c..96ee870d42b4 100644
--- a/test/CodeGen/SystemZ/rosbg-01.ll
+++ b/test/CodeGen/SystemZ/rosbg-01.ll
@@ -108,3 +108,14 @@ define i64 @f11(i64 %a, i64 %b) {
%or = or i64 %a, %andb
ret i64 %or
}
+
+; Check the handling of zext and OR, which can use ROSBG.
+define i64 @f12(i64 %a, i32 %b) {
+; CHECK-LABEL: f12:
+; CHECK: rosbg %r2, %r3, 32, 63, 0
+; CHECK: br %r14
+ %add = add i32 %b, 1
+ %ext = zext i32 %add to i64
+ %or = or i64 %a, %ext
+ ret i64 %or
+}
diff --git a/test/CodeGen/SystemZ/rxsbg-01.ll b/test/CodeGen/SystemZ/rxsbg-01.ll
index 5491bff2ecdc..339fe2a289f0 100644
--- a/test/CodeGen/SystemZ/rxsbg-01.ll
+++ b/test/CodeGen/SystemZ/rxsbg-01.ll
@@ -110,3 +110,14 @@ define i64 @f11(i64 %a, i64 %b) {
%xor = xor i64 %a, %andb
ret i64 %xor
}
+
+; Check the handling of zext and XOR, which can use ROSBG.
+define i64 @f12(i64 %a, i32 %b) {
+; CHECK-LABEL: f12:
+; CHECK: rxsbg %r2, %r3, 32, 63, 0
+; CHECK: br %r14
+ %add = add i32 %b, 1
+ %ext = zext i32 %add to i64
+ %xor = xor i64 %a, %ext
+ ret i64 %xor
+}
diff --git a/test/CodeGen/SystemZ/selectcc-01.ll b/test/CodeGen/SystemZ/selectcc-01.ll
new file mode 100644
index 000000000000..a57444c831a5
--- /dev/null
+++ b/test/CodeGen/SystemZ/selectcc-01.ll
@@ -0,0 +1,178 @@
+; Test an i32 0/-1 SELECTCCC for every floating-point condition.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test CC in { 0 }
+define i32 @f1(float %a, float %b) {
+; CHECK-LABEL: f1:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp oeq float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 1 }
+define i32 @f2(float %a, float %b) {
+; CHECK-LABEL: f2:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp olt float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 0, 1 }
+define i32 @f3(float %a, float %b) {
+; CHECK-LABEL: f3:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -536870912
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ole float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 2 }
+define i32 @f4(float %a, float %b) {
+; CHECK-LABEL: f4:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ogt float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 0, 2 }
+define i32 @f5(float %a, float %b) {
+; CHECK-LABEL: f5:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 4294967295
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp oge float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 1, 2 }
+define i32 @f6(float %a, float %b) {
+; CHECK-LABEL: f6:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp one float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 0, 1, 2 }
+define i32 @f7(float %a, float %b) {
+; CHECK-LABEL: f7:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ord float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 3 }
+define i32 @f8(float %a, float %b) {
+; CHECK-LABEL: f8:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp uno float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 0, 3 }
+define i32 @f9(float %a, float %b) {
+; CHECK-LABEL: f9:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ueq float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 1, 3 }
+define i32 @f10(float %a, float %b) {
+; CHECK-LABEL: f10:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ult float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 0, 1, 3 }
+define i32 @f11(float %a, float %b) {
+; CHECK-LABEL: f11:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ule float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 2, 3 }
+define i32 @f12(float %a, float %b) {
+; CHECK-LABEL: f12:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ugt float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 0, 2, 3 }
+define i32 @f13(float %a, float %b) {
+; CHECK-LABEL: f13:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp uge float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
+
+; Test CC in { 1, 2, 3 }
+define i32 @f14(float %a, float %b) {
+; CHECK-LABEL: f14:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp une float %a, %b
+ %res = select i1 %cond, i32 -1, i32 0
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/selectcc-02.ll b/test/CodeGen/SystemZ/selectcc-02.ll
new file mode 100644
index 000000000000..b1081a0621d6
--- /dev/null
+++ b/test/CodeGen/SystemZ/selectcc-02.ll
@@ -0,0 +1,178 @@
+; Test an i32 0/-1 SELECTCCC for every floating-point condition.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test CC in { 1, 2, 3 }
+define i32 @f1(float %a, float %b) {
+; CHECK-LABEL: f1:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp oeq float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0, 2, 3 }
+define i32 @f2(float %a, float %b) {
+; CHECK-LABEL: f2:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp olt float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 2, 3 }
+define i32 @f3(float %a, float %b) {
+; CHECK-LABEL: f3:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ole float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0, 1, 3 }
+define i32 @f4(float %a, float %b) {
+; CHECK-LABEL: f4:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ogt float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 1, 3 }
+define i32 @f5(float %a, float %b) {
+; CHECK-LABEL: f5:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp oge float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0, 3 }
+define i32 @f6(float %a, float %b) {
+; CHECK-LABEL: f6:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp one float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 3 }
+define i32 @f7(float %a, float %b) {
+; CHECK-LABEL: f7:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ord float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0, 1, 2 }
+define i32 @f8(float %a, float %b) {
+; CHECK-LABEL: f8:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp uno float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 1, 2 }
+define i32 @f9(float %a, float %b) {
+; CHECK-LABEL: f9:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ueq float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0, 2 }
+define i32 @f10(float %a, float %b) {
+; CHECK-LABEL: f10:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 4294967295
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ult float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 2 }
+define i32 @f11(float %a, float %b) {
+; CHECK-LABEL: f11:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ule float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0, 1 }
+define i32 @f12(float %a, float %b) {
+; CHECK-LABEL: f12:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -536870912
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp ugt float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 1 }
+define i32 @f13(float %a, float %b) {
+; CHECK-LABEL: f13:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp uge float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
+
+; Test CC in { 0 }
+define i32 @f14(float %a, float %b) {
+; CHECK-LABEL: f14:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+ %cond = fcmp une float %a, %b
+ %res = select i1 %cond, i32 0, i32 -1
+ ret i32 %res
+}
diff --git a/test/CodeGen/SystemZ/selectcc-03.ll b/test/CodeGen/SystemZ/selectcc-03.ll
new file mode 100644
index 000000000000..cafb4a2f1842
--- /dev/null
+++ b/test/CodeGen/SystemZ/selectcc-03.ll
@@ -0,0 +1,187 @@
+; Test an i64 0/-1 SELECTCCC for every floating-point condition.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test CC in { 0 }
+define i64 @f1(float %a, float %b) {
+; CHECK-LABEL: f1:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp oeq float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 1 }
+define i64 @f2(float %a, float %b) {
+; CHECK-LABEL: f2:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], -268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp olt float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 0, 1 }
+define i64 @f3(float %a, float %b) {
+; CHECK-LABEL: f3:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -536870912
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ole float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 2 }
+define i64 @f4(float %a, float %b) {
+; CHECK-LABEL: f4:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], 1342177280
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ogt float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 0, 2 }
+define i64 @f5(float %a, float %b) {
+; CHECK-LABEL: f5:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 4294967295
+; CHECK-NEXT: sllg [[REG]], [[REG]], 35
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp oge float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 1, 2 }
+define i64 @f6(float %a, float %b) {
+; CHECK-LABEL: f6:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], 268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 34
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp one float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 0, 1, 2 }
+define i64 @f7(float %a, float %b) {
+; CHECK-LABEL: f7:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -805306368
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ord float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 3 }
+define i64 @f8(float %a, float %b) {
+; CHECK-LABEL: f8:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], 1342177280
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp uno float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 0, 3 }
+define i64 @f9(float %a, float %b) {
+; CHECK-LABEL: f9:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 34
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ueq float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 1, 3 }
+define i64 @f10(float %a, float %b) {
+; CHECK-LABEL: f10:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: sllg [[REG]], [[REG]], 35
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ult float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 0, 1, 3 }
+define i64 @f11(float %a, float %b) {
+; CHECK-LABEL: f11:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], -805306368
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ule float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 2, 3 }
+define i64 @f12(float %a, float %b) {
+; CHECK-LABEL: f12:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: sllg [[REG]], [[REG]], 34
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp ugt float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 0, 2, 3 }
+define i64 @f13(float %a, float %b) {
+; CHECK-LABEL: f13:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], 1879048192
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp uge float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
+
+; Test CC in { 1, 2, 3 }
+define i64 @f14(float %a, float %b) {
+; CHECK-LABEL: f14:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], 1879048192
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %cond = fcmp une float %a, %b
+ %res = select i1 %cond, i64 -1, i64 0
+ ret i64 %res
+}
diff --git a/test/CodeGen/SystemZ/serialize-01.ll b/test/CodeGen/SystemZ/serialize-01.ll
new file mode 100644
index 000000000000..7801fac8d472
--- /dev/null
+++ b/test/CodeGen/SystemZ/serialize-01.ll
@@ -0,0 +1,21 @@
+; Test serialization instructions.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | \
+; RUN: FileCheck %s -check-prefix=CHECK-FULL
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | \
+; RUN: FileCheck %s -check-prefix=CHECK-FAST
+
+; Check that volatile loads produce a serialisation.
+define i32 @f1(i32 *%src) {
+; CHECK-FULL-LABEL: f1:
+; CHECK-FULL: bcr 15, %r0
+; CHECK-FULL: l %r2, 0(%r2)
+; CHECK-FULL: br %r14
+;
+; CHECK-FAST-LABEL: f1:
+; CHECK-FAST: bcr 14, %r0
+; CHECK-FAST: l %r2, 0(%r2)
+; CHECK-FAST: br %r14
+ %val = load volatile i32 *%src
+ ret i32 %val
+}
diff --git a/test/CodeGen/SystemZ/shift-04.ll b/test/CodeGen/SystemZ/shift-04.ll
index 04b39d002c5d..de2d74f27fa3 100644
--- a/test/CodeGen/SystemZ/shift-04.ll
+++ b/test/CodeGen/SystemZ/shift-04.ll
@@ -187,3 +187,104 @@ define i32 @f14(i32 %a, i32 *%ptr) {
%or = or i32 %parta, %partb
ret i32 %or
}
+
+; Check another form of f5, which is the one produced by running f5 through
+; instcombine.
+define i32 @f15(i32 %a, i32 %amt) {
+; CHECK-LABEL: f15:
+; CHECK: rll %r2, %r2, 10(%r3)
+; CHECK: br %r14
+ %add = add i32 %amt, 10
+ %sub = sub i32 22, %amt
+ %parta = shl i32 %a, %add
+ %partb = lshr i32 %a, %sub
+ %or = or i32 %parta, %partb
+ ret i32 %or
+}
+
+; Likewise for f7.
+define i32 @f16(i32 %a, i64 %amt) {
+; CHECK-LABEL: f16:
+; CHECK: rll %r2, %r2, 10(%r3)
+; CHECK: br %r14
+ %add = add i64 %amt, 10
+ %sub = sub i64 22, %amt
+ %addtrunc = trunc i64 %add to i32
+ %subtrunc = trunc i64 %sub to i32
+ %parta = shl i32 %a, %addtrunc
+ %partb = lshr i32 %a, %subtrunc
+ %or = or i32 %parta, %partb
+ ret i32 %or
+}
+
+; Check cases where (-x & 31) is used instead of 32 - x.
+define i32 @f17(i32 %x, i32 %y) {
+; CHECK-LABEL: f17:
+; CHECK: rll %r2, %r2, 0(%r3)
+; CHECK: br %r14
+entry:
+ %shl = shl i32 %x, %y
+ %sub = sub i32 0, %y
+ %and = and i32 %sub, 31
+ %shr = lshr i32 %x, %and
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
+
+; ...and again with ((32 - x) & 31).
+define i32 @f18(i32 %x, i32 %y) {
+; CHECK-LABEL: f18:
+; CHECK: rll %r2, %r2, 0(%r3)
+; CHECK: br %r14
+entry:
+ %shl = shl i32 %x, %y
+ %sub = sub i32 32, %y
+ %and = and i32 %sub, 31
+ %shr = lshr i32 %x, %and
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
+
+; This is not a rotation.
+define i32 @f19(i32 %x, i32 %y) {
+; CHECK-LABEL: f19:
+; CHECK-NOT: rll
+; CHECK: br %r14
+entry:
+ %shl = shl i32 %x, %y
+ %sub = sub i32 16, %y
+ %and = and i32 %sub, 31
+ %shr = lshr i32 %x, %and
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
+
+; Repeat f17 with an addition on the shift count.
+define i32 @f20(i32 %x, i32 %y) {
+; CHECK-LABEL: f20:
+; CHECK: rll %r2, %r2, 199(%r3)
+; CHECK: br %r14
+entry:
+ %add = add i32 %y, 199
+ %shl = shl i32 %x, %add
+ %sub = sub i32 0, %add
+ %and = and i32 %sub, 31
+ %shr = lshr i32 %x, %and
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
+
+; ...and again with the InstCombine version.
+define i32 @f21(i32 %x, i32 %y) {
+; CHECK-LABEL: f21:
+; CHECK: rll %r2, %r2, 199(%r3)
+; CHECK: br %r14
+entry:
+ %add = add i32 %y, 199
+ %shl = shl i32 %x, %add
+ %sub = sub i32 -199, %y
+ %and = and i32 %sub, 31
+ %shr = lshr i32 %x, %and
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
diff --git a/test/CodeGen/SystemZ/shift-10.ll b/test/CodeGen/SystemZ/shift-10.ll
index 46ed2180dfd4..bf2f0f1776ee 100644
--- a/test/CodeGen/SystemZ/shift-10.ll
+++ b/test/CodeGen/SystemZ/shift-10.ll
@@ -14,13 +14,14 @@ define i64 @f1(i32 %a) {
ret i64 %ext
}
-; ...and again with the highest shift count.
+; ...and again with the highest shift count that doesn't reduce to an
+; ashr/sext pair.
define i64 @f2(i32 %a) {
; CHECK-LABEL: f2:
-; CHECK: sllg [[REG:%r[0-5]]], %r2, 32
+; CHECK: sllg [[REG:%r[0-5]]], %r2, 33
; CHECK: srag %r2, [[REG]], 63
; CHECK: br %r14
- %shr = lshr i32 %a, 31
+ %shr = lshr i32 %a, 30
%trunc = trunc i32 %shr to i1
%ext = sext i1 %trunc to i64
ret i64 %ext
@@ -76,3 +77,15 @@ define i64 @f6(i64 %a) {
%and = and i64 %shr, 256
ret i64 %and
}
+
+; Test another form of f1.
+define i64 @f7(i32 %a) {
+; CHECK-LABEL: f7:
+; CHECK: sllg [[REG:%r[0-5]]], %r2, 62
+; CHECK: srag %r2, [[REG]], 63
+; CHECK: br %r14
+ %1 = shl i32 %a, 30
+ %sext = ashr i32 %1, 31
+ %ext = sext i32 %sext to i64
+ ret i64 %ext
+}
diff --git a/test/CodeGen/SystemZ/spill-01.ll b/test/CodeGen/SystemZ/spill-01.ll
index ca64a88f2a0d..c1f780c55d3c 100644
--- a/test/CodeGen/SystemZ/spill-01.ll
+++ b/test/CodeGen/SystemZ/spill-01.ll
@@ -400,6 +400,7 @@ define void @f10() {
; CHECK: stgrl [[REG]], h8
; CHECK: br %r14
entry:
+ %val8 = load volatile i64 *@h8
%val0 = load volatile i64 *@h0
%val1 = load volatile i64 *@h1
%val2 = load volatile i64 *@h2
@@ -408,7 +409,6 @@ entry:
%val5 = load volatile i64 *@h5
%val6 = load volatile i64 *@h6
%val7 = load volatile i64 *@h7
- %val8 = load volatile i64 *@h8
%val9 = load volatile i64 *@h9
call void @foo()