1*9880d681SAndroid Build Coastguard Worker; Test 16-bit conditional stores that are presented as selects. The volatile 2*9880d681SAndroid Build Coastguard Worker; tests require z10, which use a branch instead of a LOCR. 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i16 *) 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; Test the simple case, with the loaded value first. 9*9880d681SAndroid Build Coastguard Workerdefine void @f1(i16 *%ptr, i16 %alt, i32 %limit) { 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 12*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 13*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 14*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 15*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 16*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 17*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 18*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 19*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 20*9880d681SAndroid Build Coastguard Worker ret void 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 24*9880d681SAndroid Build Coastguard Workerdefine void @f2(i16 *%ptr, i16 %alt, i32 %limit) { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 26*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 27*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14 28*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 29*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 30*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 31*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 32*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 33*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %alt, i16 %orig 34*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly sign-extended to 32 bits, with the 39*9880d681SAndroid Build Coastguard Worker; loaded value first. 40*9880d681SAndroid Build Coastguard Workerdefine void @f3(i16 *%ptr, i32 %alt, i32 %limit) { 41*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 42*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 43*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 44*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 45*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 46*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 47*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 48*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 49*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %orig to i32 50*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %ext, i32 %alt 51*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %res to i16 52*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 53*9880d681SAndroid Build Coastguard Worker ret void 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 57*9880d681SAndroid Build Coastguard Workerdefine void @f4(i16 *%ptr, i32 %alt, i32 %limit) { 58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 59*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 60*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14 61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 62*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 63*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 64*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 65*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 66*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %orig to i32 67*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %alt, i32 %ext 68*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %res to i16 69*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 70*9880d681SAndroid Build Coastguard Worker ret void 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly zero-extended to 32 bits, with the 74*9880d681SAndroid Build Coastguard Worker; loaded value first. 75*9880d681SAndroid Build Coastguard Workerdefine void @f5(i16 *%ptr, i32 %alt, i32 %limit) { 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 77*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 78*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 79*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 80*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 81*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 82*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 83*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 84*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %orig to i32 85*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %ext, i32 %alt 86*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %res to i16 87*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 88*9880d681SAndroid Build Coastguard Worker ret void 89*9880d681SAndroid Build Coastguard Worker} 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 92*9880d681SAndroid Build Coastguard Workerdefine void @f6(i16 *%ptr, i32 %alt, i32 %limit) { 93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 94*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 95*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14 96*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 97*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 98*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 99*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 100*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 101*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %orig to i32 102*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %alt, i32 %ext 103*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %res to i16 104*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 105*9880d681SAndroid Build Coastguard Worker ret void 106*9880d681SAndroid Build Coastguard Worker} 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly sign-extended to 64 bits, with the 109*9880d681SAndroid Build Coastguard Worker; loaded value first. 110*9880d681SAndroid Build Coastguard Workerdefine void @f7(i16 *%ptr, i64 %alt, i32 %limit) { 111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 112*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 113*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 114*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 115*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 116*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 117*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 118*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 119*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %orig to i64 120*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %ext, i64 %alt 121*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i16 122*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 123*9880d681SAndroid Build Coastguard Worker ret void 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 127*9880d681SAndroid Build Coastguard Workerdefine void @f8(i16 *%ptr, i64 %alt, i32 %limit) { 128*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 129*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 130*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14 131*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 132*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 133*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 134*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 135*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 136*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %orig to i64 137*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %alt, i64 %ext 138*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i16 139*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 140*9880d681SAndroid Build Coastguard Worker ret void 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly zero-extended to 64 bits, with the 144*9880d681SAndroid Build Coastguard Worker; loaded value first. 145*9880d681SAndroid Build Coastguard Workerdefine void @f9(i16 *%ptr, i64 %alt, i32 %limit) { 146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 147*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 148*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 149*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 150*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 151*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 152*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 153*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 154*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %orig to i64 155*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %ext, i64 %alt 156*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i16 157*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 158*9880d681SAndroid Build Coastguard Worker ret void 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 162*9880d681SAndroid Build Coastguard Workerdefine void @f10(i16 *%ptr, i64 %alt, i32 %limit) { 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 164*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 165*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14 166*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 167*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 168*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 169*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 170*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 171*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %orig to i64 172*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %alt, i64 %ext 173*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i16 174*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16 *%ptr 175*9880d681SAndroid Build Coastguard Worker ret void 176*9880d681SAndroid Build Coastguard Worker} 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned STH range. 179*9880d681SAndroid Build Coastguard Workerdefine void @f11(i16 *%base, i16 %alt, i32 %limit) { 180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 181*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 182*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 183*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 184*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 4094(%r2) 185*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 186*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i16, i16 *%base, i64 2047 187*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 188*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 189*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 190*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 191*9880d681SAndroid Build Coastguard Worker ret void 192*9880d681SAndroid Build Coastguard Worker} 193*9880d681SAndroid Build Coastguard Worker 194*9880d681SAndroid Build Coastguard Worker; Check the next halfword up, which should use STHY instead of STH. 195*9880d681SAndroid Build Coastguard Workerdefine void @f12(i16 *%base, i16 %alt, i32 %limit) { 196*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 197*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 198*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 199*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 200*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r3, 4096(%r2) 201*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 202*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i16, i16 *%base, i64 2048 203*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 204*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 205*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 206*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 207*9880d681SAndroid Build Coastguard Worker ret void 208*9880d681SAndroid Build Coastguard Worker} 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned STHY range. 211*9880d681SAndroid Build Coastguard Workerdefine void @f13(i16 *%base, i16 %alt, i32 %limit) { 212*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 213*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 214*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 215*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 216*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r3, 524286(%r2) 217*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 218*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i16, i16 *%base, i64 262143 219*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 220*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 221*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 222*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 223*9880d681SAndroid Build Coastguard Worker ret void 224*9880d681SAndroid Build Coastguard Worker} 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Worker; Check the next halfword up, which needs separate address logic. 227*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK. 228*9880d681SAndroid Build Coastguard Workerdefine void @f14(i16 *%base, i16 %alt, i32 %limit) { 229*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14: 230*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 231*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 232*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 233*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r2, 524288 234*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 235*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 236*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i16, i16 *%base, i64 262144 237*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 238*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 239*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 240*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 241*9880d681SAndroid Build Coastguard Worker ret void 242*9880d681SAndroid Build Coastguard Worker} 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Worker; Check the low end of the STHY range. 245*9880d681SAndroid Build Coastguard Workerdefine void @f15(i16 *%base, i16 %alt, i32 %limit) { 246*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15: 247*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 248*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 249*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 250*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r3, -524288(%r2) 251*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 252*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i16, i16 *%base, i64 -262144 253*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 254*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 255*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 256*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 257*9880d681SAndroid Build Coastguard Worker ret void 258*9880d681SAndroid Build Coastguard Worker} 259*9880d681SAndroid Build Coastguard Worker 260*9880d681SAndroid Build Coastguard Worker; Check the next halfword down, which needs separate address logic. 261*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK. 262*9880d681SAndroid Build Coastguard Workerdefine void @f16(i16 *%base, i16 %alt, i32 %limit) { 263*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16: 264*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 265*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 266*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 267*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r2, -524290 268*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 269*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 270*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i16, i16 *%base, i64 -262145 271*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 272*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 273*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 274*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 275*9880d681SAndroid Build Coastguard Worker ret void 276*9880d681SAndroid Build Coastguard Worker} 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker; Check that STHY allows an index. 279*9880d681SAndroid Build Coastguard Workerdefine void @f17(i64 %base, i64 %index, i16 %alt, i32 %limit) { 280*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17: 281*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 282*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 283*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 284*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r4, 4096(%r3,%r2) 285*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 286*9880d681SAndroid Build Coastguard Worker %add1 = add i64 %base, %index 287*9880d681SAndroid Build Coastguard Worker %add2 = add i64 %add1, 4096 288*9880d681SAndroid Build Coastguard Worker %ptr = inttoptr i64 %add2 to i16 * 289*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 290*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 291*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 292*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 293*9880d681SAndroid Build Coastguard Worker ret void 294*9880d681SAndroid Build Coastguard Worker} 295*9880d681SAndroid Build Coastguard Worker 296*9880d681SAndroid Build Coastguard Worker; Check that volatile loads are not matched. 297*9880d681SAndroid Build Coastguard Workerdefine void @f18(i16 *%ptr, i16 %alt, i32 %limit) { 298*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f18: 299*9880d681SAndroid Build Coastguard Worker; CHECK: lh {{%r[0-5]}}, 0(%r2) 300*9880d681SAndroid Build Coastguard Worker; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]] 301*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 302*9880d681SAndroid Build Coastguard Worker; CHECK: sth {{%r[0-5]}}, 0(%r2) 303*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 304*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 305*9880d681SAndroid Build Coastguard Worker %orig = load volatile i16 , i16 *%ptr 306*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 307*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 308*9880d681SAndroid Build Coastguard Worker ret void 309*9880d681SAndroid Build Coastguard Worker} 310*9880d681SAndroid Build Coastguard Worker 311*9880d681SAndroid Build Coastguard Worker; ...likewise stores. In this case we should have a conditional load into %r3. 312*9880d681SAndroid Build Coastguard Workerdefine void @f19(i16 *%ptr, i16 %alt, i32 %limit) { 313*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f19: 314*9880d681SAndroid Build Coastguard Worker; CHECK: jhe [[LABEL:[^ ]*]] 315*9880d681SAndroid Build Coastguard Worker; CHECK: lh %r3, 0(%r2) 316*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 317*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 318*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 319*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 320*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 321*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 322*9880d681SAndroid Build Coastguard Worker store volatile i16 %res, i16 *%ptr 323*9880d681SAndroid Build Coastguard Worker ret void 324*9880d681SAndroid Build Coastguard Worker} 325*9880d681SAndroid Build Coastguard Worker 326*9880d681SAndroid Build Coastguard Worker; Check that atomic loads are not matched. The transformation is OK for 327*9880d681SAndroid Build Coastguard Worker; the "unordered" case tested here, but since we don't try to handle atomic 328*9880d681SAndroid Build Coastguard Worker; operations at all in this context, it seems better to assert that than 329*9880d681SAndroid Build Coastguard Worker; to restrict the test to a stronger ordering. 330*9880d681SAndroid Build Coastguard Workerdefine void @f20(i16 *%ptr, i16 %alt, i32 %limit) { 331*9880d681SAndroid Build Coastguard Worker; FIXME: should use a normal load instead of CS. 332*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f20: 333*9880d681SAndroid Build Coastguard Worker; CHECK: lh {{%r[0-9]+}}, 0(%r2) 334*9880d681SAndroid Build Coastguard Worker; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]] 335*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 336*9880d681SAndroid Build Coastguard Worker; CHECK: sth {{%r[0-9]+}}, 0(%r2) 337*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 338*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 339*9880d681SAndroid Build Coastguard Worker %orig = load atomic i16 , i16 *%ptr unordered, align 2 340*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 341*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 342*9880d681SAndroid Build Coastguard Worker ret void 343*9880d681SAndroid Build Coastguard Worker} 344*9880d681SAndroid Build Coastguard Worker 345*9880d681SAndroid Build Coastguard Worker; ...likewise stores. 346*9880d681SAndroid Build Coastguard Workerdefine void @f21(i16 *%ptr, i16 %alt, i32 %limit) { 347*9880d681SAndroid Build Coastguard Worker; FIXME: should use a normal store instead of CS. 348*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f21: 349*9880d681SAndroid Build Coastguard Worker; CHECK: jhe [[LABEL:[^ ]*]] 350*9880d681SAndroid Build Coastguard Worker; CHECK: lh %r3, 0(%r2) 351*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 352*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2) 353*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 354*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 355*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 356*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 357*9880d681SAndroid Build Coastguard Worker store atomic i16 %res, i16 *%ptr unordered, align 2 358*9880d681SAndroid Build Coastguard Worker ret void 359*9880d681SAndroid Build Coastguard Worker} 360*9880d681SAndroid Build Coastguard Worker 361*9880d681SAndroid Build Coastguard Worker; Try a frame index base. 362*9880d681SAndroid Build Coastguard Workerdefine void @f22(i16 %alt, i32 %limit) { 363*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f22: 364*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 365*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r15 366*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LABEL:[^ ]*]] 367*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r15 368*9880d681SAndroid Build Coastguard Worker; CHECK: sth {{%r[0-9]+}}, {{[0-9]+}}(%r15) 369*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 370*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 371*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 372*9880d681SAndroid Build Coastguard Worker %ptr = alloca i16 373*9880d681SAndroid Build Coastguard Worker call void @foo(i16 *%ptr) 374*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 420 375*9880d681SAndroid Build Coastguard Worker %orig = load i16 , i16 *%ptr 376*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i16 %orig, i16 %alt 377*9880d681SAndroid Build Coastguard Worker store i16 %res, i16 *%ptr 378*9880d681SAndroid Build Coastguard Worker call void @foo(i16 *%ptr) 379*9880d681SAndroid Build Coastguard Worker ret void 380*9880d681SAndroid Build Coastguard Worker} 381