1*9880d681SAndroid Build Coastguard Worker; Test STOCs that are presented as selects. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i32 *) 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Test the simple case, with the loaded value first. 8*9880d681SAndroid Build Coastguard Workerdefine void @f1(i32 *%ptr, i32 %alt, i32 %limit) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 10*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 11*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, 0(%r2) 12*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 13*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 14*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 15*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %orig, i32 %alt 16*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 17*9880d681SAndroid Build Coastguard Worker ret void 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 21*9880d681SAndroid Build Coastguard Workerdefine void @f2(i32 *%ptr, i32 %alt, i32 %limit) { 22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 23*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 24*9880d681SAndroid Build Coastguard Worker; CHECK: stocl %r3, 0(%r2) 25*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 26*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 27*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 28*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %alt, i32 %orig 29*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 30*9880d681SAndroid Build Coastguard Worker ret void 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly sign-extended to 64 bits, with the 34*9880d681SAndroid Build Coastguard Worker; loaded value first. 35*9880d681SAndroid Build Coastguard Workerdefine void @f3(i32 *%ptr, i64 %alt, i32 %limit) { 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 37*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 38*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, 0(%r2) 39*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 40*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 41*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 42*9880d681SAndroid Build Coastguard Worker %ext = sext i32 %orig to i64 43*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %ext, i64 %alt 44*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i32 45*9880d681SAndroid Build Coastguard Worker store i32 %trunc, i32 *%ptr 46*9880d681SAndroid Build Coastguard Worker ret void 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 50*9880d681SAndroid Build Coastguard Workerdefine void @f4(i32 *%ptr, i64 %alt, i32 %limit) { 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 52*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 53*9880d681SAndroid Build Coastguard Worker; CHECK: stocl %r3, 0(%r2) 54*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 55*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 56*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 57*9880d681SAndroid Build Coastguard Worker %ext = sext i32 %orig to i64 58*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %alt, i64 %ext 59*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i32 60*9880d681SAndroid Build Coastguard Worker store i32 %trunc, i32 *%ptr 61*9880d681SAndroid Build Coastguard Worker ret void 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly zero-extended to 32 bits, with the 65*9880d681SAndroid Build Coastguard Worker; loaded value first. 66*9880d681SAndroid Build Coastguard Workerdefine void @f5(i32 *%ptr, i64 %alt, i32 %limit) { 67*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 68*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 69*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, 0(%r2) 70*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 71*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 72*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 73*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %orig to i64 74*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %ext, i64 %alt 75*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i32 76*9880d681SAndroid Build Coastguard Worker store i32 %trunc, i32 *%ptr 77*9880d681SAndroid Build Coastguard Worker ret void 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second 81*9880d681SAndroid Build Coastguard Workerdefine void @f6(i32 *%ptr, i64 %alt, i32 %limit) { 82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 83*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 84*9880d681SAndroid Build Coastguard Worker; CHECK: stocl %r3, 0(%r2) 85*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 86*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 87*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 88*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %orig to i64 89*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %alt, i64 %ext 90*9880d681SAndroid Build Coastguard Worker %trunc = trunc i64 %res to i32 91*9880d681SAndroid Build Coastguard Worker store i32 %trunc, i32 *%ptr 92*9880d681SAndroid Build Coastguard Worker ret void 93*9880d681SAndroid Build Coastguard Worker} 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned STOC range. 96*9880d681SAndroid Build Coastguard Workerdefine void @f7(i32 *%base, i32 %alt, i32 %limit) { 97*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 98*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 99*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, 524284(%r2) 100*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 101*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 131071 102*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 103*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 104*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %orig, i32 %alt 105*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 106*9880d681SAndroid Build Coastguard Worker ret void 107*9880d681SAndroid Build Coastguard Worker} 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker; Check the next word up. Other sequences besides this one would be OK. 110*9880d681SAndroid Build Coastguard Workerdefine void @f8(i32 *%base, i32 %alt, i32 %limit) { 111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 112*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r2, 524288 113*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 114*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, 0(%r2) 115*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 116*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 131072 117*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 118*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 119*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %orig, i32 %alt 120*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 121*9880d681SAndroid Build Coastguard Worker ret void 122*9880d681SAndroid Build Coastguard Worker} 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker; Check the low end of the STOC range. 125*9880d681SAndroid Build Coastguard Workerdefine void @f9(i32 *%base, i32 %alt, i32 %limit) { 126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 127*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 128*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, -524288(%r2) 129*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 130*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 -131072 131*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 132*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 133*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %orig, i32 %alt 134*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 135*9880d681SAndroid Build Coastguard Worker ret void 136*9880d681SAndroid Build Coastguard Worker} 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker; Check the next word down, with the same comments as f8. 139*9880d681SAndroid Build Coastguard Workerdefine void @f10(i32 *%base, i32 %alt, i32 %limit) { 140*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 141*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r2, -524292 142*9880d681SAndroid Build Coastguard Worker; CHECK: clfi %r4, 42 143*9880d681SAndroid Build Coastguard Worker; CHECK: stoche %r3, 0(%r2) 144*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 145*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 -131073 146*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 147*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 148*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %orig, i32 %alt 149*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 150*9880d681SAndroid Build Coastguard Worker ret void 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker; Try a frame index base. 154*9880d681SAndroid Build Coastguard Workerdefine void @f11(i32 %alt, i32 %limit) { 155*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 156*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 157*9880d681SAndroid Build Coastguard Worker; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15) 158*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 159*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 160*9880d681SAndroid Build Coastguard Worker %ptr = alloca i32 161*9880d681SAndroid Build Coastguard Worker call void @foo(i32 *%ptr) 162*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %limit, 42 163*9880d681SAndroid Build Coastguard Worker %orig = load i32 , i32 *%ptr 164*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i32 %orig, i32 %alt 165*9880d681SAndroid Build Coastguard Worker store i32 %res, i32 *%ptr 166*9880d681SAndroid Build Coastguard Worker call void @foo(i32 *%ptr) 167*9880d681SAndroid Build Coastguard Worker ret void 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker; Test that conditionally-executed stores do not use STOC, since STOC 171*9880d681SAndroid Build Coastguard Worker; is allowed to trap even when the condition is false. 172*9880d681SAndroid Build Coastguard Workerdefine void @f12(i32 %a, i32 %b, i32 *%dest) { 173*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 174*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: stoc 175*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 176*9880d681SAndroid Build Coastguard Workerentry: 177*9880d681SAndroid Build Coastguard Worker %cmp = icmp ule i32 %a, %b 178*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %store, label %exit 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Workerstore: 181*9880d681SAndroid Build Coastguard Worker store i32 %b, i32 *%dest 182*9880d681SAndroid Build Coastguard Worker br label %exit 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Workerexit: 185*9880d681SAndroid Build Coastguard Worker ret void 186*9880d681SAndroid Build Coastguard Worker} 187