1*9880d681SAndroid Build Coastguard Worker; Test 8-bit atomic min/max operations. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT1 5*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT2 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Check signed minimum. 8*9880d681SAndroid Build Coastguard Worker; - CHECK is for the main loop. 9*9880d681SAndroid Build Coastguard Worker; - CHECK-SHIFT1 makes sure that the negated shift count used by the second 10*9880d681SAndroid Build Coastguard Worker; RLL is set up correctly. The negation is independent of the NILL and L 11*9880d681SAndroid Build Coastguard Worker; tested in CHECK. 12*9880d681SAndroid Build Coastguard Worker; - CHECK-SHIFT2 makes sure that %b is shifted into the high part of the word 13*9880d681SAndroid Build Coastguard Worker; before being used, and that the low bits are set to 1. This sequence is 14*9880d681SAndroid Build Coastguard Worker; independent of the other loop prologue instructions. 15*9880d681SAndroid Build Coastguard Workerdefine i8 @f1(i8 *%src, i8 %b) { 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 17*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}} 18*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 3 19*9880d681SAndroid Build Coastguard Worker; CHECK: l [[OLD:%r[0-9]+]], 0([[RISBG]]) 20*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:\.[^:]*]]: 21*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0(%r2) 22*9880d681SAndroid Build Coastguard Worker; CHECK: crjle [[ROT]], %r3, [[KEEP:\..*]] 23*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], %r3, 32, 39, 0 24*9880d681SAndroid Build Coastguard Worker; CHECK: [[KEEP]]: 25*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) 26*9880d681SAndroid Build Coastguard Worker; CHECK: cs [[OLD]], [[NEW]], 0([[RISBG]]) 27*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LOOP]] 28*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[OLD]], 8(%r2) 29*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 30*9880d681SAndroid Build Coastguard Worker; 31*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f1: 32*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: sll %r2, 3 33*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], %r2 34*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 35*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]]) 36*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 37*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 38*9880d681SAndroid Build Coastguard Worker; 39*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f1: 40*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: sll %r3, 24 41*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 42*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: crjle {{%r[0-9]+}}, %r3 43*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 44*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 45*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 46*9880d681SAndroid Build Coastguard Worker %res = atomicrmw min i8 *%src, i8 %b seq_cst 47*9880d681SAndroid Build Coastguard Worker ret i8 %res 48*9880d681SAndroid Build Coastguard Worker} 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; Check signed maximum. 51*9880d681SAndroid Build Coastguard Workerdefine i8 @f2(i8 *%src, i8 %b) { 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 53*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}} 54*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 3 55*9880d681SAndroid Build Coastguard Worker; CHECK: l [[OLD:%r[0-9]+]], 0([[RISBG]]) 56*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:\.[^:]*]]: 57*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0(%r2) 58*9880d681SAndroid Build Coastguard Worker; CHECK: crjhe [[ROT]], %r3, [[KEEP:\..*]] 59*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], %r3, 32, 39, 0 60*9880d681SAndroid Build Coastguard Worker; CHECK: [[KEEP]]: 61*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) 62*9880d681SAndroid Build Coastguard Worker; CHECK: cs [[OLD]], [[NEW]], 0([[RISBG]]) 63*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LOOP]] 64*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[OLD]], 8(%r2) 65*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 66*9880d681SAndroid Build Coastguard Worker; 67*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f2: 68*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: sll %r2, 3 69*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], %r2 70*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 71*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]]) 72*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 73*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 74*9880d681SAndroid Build Coastguard Worker; 75*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f2: 76*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: sll %r3, 24 77*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 78*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: crjhe {{%r[0-9]+}}, %r3 79*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 80*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 81*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 82*9880d681SAndroid Build Coastguard Worker %res = atomicrmw max i8 *%src, i8 %b seq_cst 83*9880d681SAndroid Build Coastguard Worker ret i8 %res 84*9880d681SAndroid Build Coastguard Worker} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker; Check unsigned minimum. 87*9880d681SAndroid Build Coastguard Workerdefine i8 @f3(i8 *%src, i8 %b) { 88*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 89*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}} 90*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 3 91*9880d681SAndroid Build Coastguard Worker; CHECK: l [[OLD:%r[0-9]+]], 0([[RISBG]]) 92*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:\.[^:]*]]: 93*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0(%r2) 94*9880d681SAndroid Build Coastguard Worker; CHECK: clrjle [[ROT]], %r3, [[KEEP:\..*]] 95*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], %r3, 32, 39, 0 96*9880d681SAndroid Build Coastguard Worker; CHECK: [[KEEP]]: 97*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) 98*9880d681SAndroid Build Coastguard Worker; CHECK: cs [[OLD]], [[NEW]], 0([[RISBG]]) 99*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LOOP]] 100*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[OLD]], 8(%r2) 101*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 102*9880d681SAndroid Build Coastguard Worker; 103*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f3: 104*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: sll %r2, 3 105*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], %r2 106*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 107*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]]) 108*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 109*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 110*9880d681SAndroid Build Coastguard Worker; 111*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f3: 112*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: sll %r3, 24 113*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 114*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: clrjle {{%r[0-9]+}}, %r3, 115*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 116*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 117*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 118*9880d681SAndroid Build Coastguard Worker %res = atomicrmw umin i8 *%src, i8 %b seq_cst 119*9880d681SAndroid Build Coastguard Worker ret i8 %res 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker; Check unsigned maximum. 123*9880d681SAndroid Build Coastguard Workerdefine i8 @f4(i8 *%src, i8 %b) { 124*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 125*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}} 126*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 3 127*9880d681SAndroid Build Coastguard Worker; CHECK: l [[OLD:%r[0-9]+]], 0([[RISBG]]) 128*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:\.[^:]*]]: 129*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0(%r2) 130*9880d681SAndroid Build Coastguard Worker; CHECK: clrjhe [[ROT]], %r3, [[KEEP:\..*]] 131*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], %r3, 32, 39, 0 132*9880d681SAndroid Build Coastguard Worker; CHECK: [[KEEP]]: 133*9880d681SAndroid Build Coastguard Worker; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) 134*9880d681SAndroid Build Coastguard Worker; CHECK: cs [[OLD]], [[NEW]], 0([[RISBG]]) 135*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LOOP]] 136*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[OLD]], 8(%r2) 137*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 138*9880d681SAndroid Build Coastguard Worker; 139*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f4: 140*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: sll %r2, 3 141*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], %r2 142*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 143*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]]) 144*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: rll 145*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 146*9880d681SAndroid Build Coastguard Worker; 147*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f4: 148*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: sll %r3, 24 149*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 150*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: clrjhe {{%r[0-9]+}}, %r3, 151*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 152*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: rll 153*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 154*9880d681SAndroid Build Coastguard Worker %res = atomicrmw umax i8 *%src, i8 %b seq_cst 155*9880d681SAndroid Build Coastguard Worker ret i8 %res 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; Check the lowest useful signed minimum value. We need to load 0x81000000 159*9880d681SAndroid Build Coastguard Worker; into the source register. 160*9880d681SAndroid Build Coastguard Workerdefine i8 @f5(i8 *%src) { 161*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 162*9880d681SAndroid Build Coastguard Worker; CHECK: llilh [[SRC2:%r[0-9]+]], 33024 163*9880d681SAndroid Build Coastguard Worker; CHECK: crjle [[ROT:%r[0-9]+]], [[SRC2]] 164*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0 165*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 166*9880d681SAndroid Build Coastguard Worker; 167*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f5: 168*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 169*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f5: 170*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 171*9880d681SAndroid Build Coastguard Worker %res = atomicrmw min i8 *%src, i8 -127 seq_cst 172*9880d681SAndroid Build Coastguard Worker ret i8 %res 173*9880d681SAndroid Build Coastguard Worker} 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker; Check the highest useful signed maximum value. We need to load 0x7e000000 176*9880d681SAndroid Build Coastguard Worker; into the source register. 177*9880d681SAndroid Build Coastguard Workerdefine i8 @f6(i8 *%src) { 178*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 179*9880d681SAndroid Build Coastguard Worker; CHECK: llilh [[SRC2:%r[0-9]+]], 32256 180*9880d681SAndroid Build Coastguard Worker; CHECK: crjhe [[ROT:%r[0-9]+]], [[SRC2]] 181*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0 182*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 183*9880d681SAndroid Build Coastguard Worker; 184*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f6: 185*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 186*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f6: 187*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 188*9880d681SAndroid Build Coastguard Worker %res = atomicrmw max i8 *%src, i8 126 seq_cst 189*9880d681SAndroid Build Coastguard Worker ret i8 %res 190*9880d681SAndroid Build Coastguard Worker} 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker; Check the lowest useful unsigned minimum value. We need to load 0x01000000 193*9880d681SAndroid Build Coastguard Worker; into the source register. 194*9880d681SAndroid Build Coastguard Workerdefine i8 @f7(i8 *%src) { 195*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 196*9880d681SAndroid Build Coastguard Worker; CHECK: llilh [[SRC2:%r[0-9]+]], 256 197*9880d681SAndroid Build Coastguard Worker; CHECK: clrjle [[ROT:%r[0-9]+]], [[SRC2]], 198*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0 199*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 200*9880d681SAndroid Build Coastguard Worker; 201*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f7: 202*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 203*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f7: 204*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 205*9880d681SAndroid Build Coastguard Worker %res = atomicrmw umin i8 *%src, i8 1 seq_cst 206*9880d681SAndroid Build Coastguard Worker ret i8 %res 207*9880d681SAndroid Build Coastguard Worker} 208*9880d681SAndroid Build Coastguard Worker 209*9880d681SAndroid Build Coastguard Worker; Check the highest useful unsigned maximum value. We need to load 0xfe000000 210*9880d681SAndroid Build Coastguard Worker; into the source register. 211*9880d681SAndroid Build Coastguard Workerdefine i8 @f8(i8 *%src) { 212*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 213*9880d681SAndroid Build Coastguard Worker; CHECK: llilh [[SRC2:%r[0-9]+]], 65024 214*9880d681SAndroid Build Coastguard Worker; CHECK: clrjhe [[ROT:%r[0-9]+]], [[SRC2]], 215*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0 216*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 217*9880d681SAndroid Build Coastguard Worker; 218*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1-LABEL: f8: 219*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT1: br %r14 220*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2-LABEL: f8: 221*9880d681SAndroid Build Coastguard Worker; CHECK-SHIFT2: br %r14 222*9880d681SAndroid Build Coastguard Worker %res = atomicrmw umax i8 *%src, i8 254 seq_cst 223*9880d681SAndroid Build Coastguard Worker ret i8 %res 224*9880d681SAndroid Build Coastguard Worker} 225