1; Test STOCGs that are presented as selects. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 4 5declare void @foo(i64 *) 6 7; Test with the loaded value first. 8define void @f1(i64 *%ptr, i64 %alt, i32 %limit) { 9; CHECK-LABEL: f1: 10; CHECK: clfi %r4, 42 11; CHECK: stocghe %r3, 0(%r2) 12; CHECK: br %r14 13 %cond = icmp ult i32 %limit, 42 14 %orig = load i64, i64 *%ptr 15 %res = select i1 %cond, i64 %orig, i64 %alt 16 store i64 %res, i64 *%ptr 17 ret void 18} 19 20; ...and with the loaded value second 21define void @f2(i64 *%ptr, i64 %alt, i32 %limit) { 22; CHECK-LABEL: f2: 23; CHECK: clfi %r4, 42 24; CHECK: stocgl %r3, 0(%r2) 25; CHECK: br %r14 26 %cond = icmp ult i32 %limit, 42 27 %orig = load i64, i64 *%ptr 28 %res = select i1 %cond, i64 %alt, i64 %orig 29 store i64 %res, i64 *%ptr 30 ret void 31} 32 33; Check the high end of the aligned STOCG range. 34define void @f3(i64 *%base, i64 %alt, i32 %limit) { 35; CHECK-LABEL: f3: 36; CHECK: clfi %r4, 42 37; CHECK: stocghe %r3, 524280(%r2) 38; CHECK: br %r14 39 %ptr = getelementptr i64, i64 *%base, i64 65535 40 %cond = icmp ult i32 %limit, 42 41 %orig = load i64, i64 *%ptr 42 %res = select i1 %cond, i64 %orig, i64 %alt 43 store i64 %res, i64 *%ptr 44 ret void 45} 46 47; Check the next doubleword up. Other sequences besides this one would be OK. 48define void @f4(i64 *%base, i64 %alt, i32 %limit) { 49; CHECK-LABEL: f4: 50; CHECK: agfi %r2, 524288 51; CHECK: clfi %r4, 42 52; CHECK: stocghe %r3, 0(%r2) 53; CHECK: br %r14 54 %ptr = getelementptr i64, i64 *%base, i64 65536 55 %cond = icmp ult i32 %limit, 42 56 %orig = load i64, i64 *%ptr 57 %res = select i1 %cond, i64 %orig, i64 %alt 58 store i64 %res, i64 *%ptr 59 ret void 60} 61 62; Check the low end of the STOCG range. 63define void @f5(i64 *%base, i64 %alt, i32 %limit) { 64; CHECK-LABEL: f5: 65; CHECK: clfi %r4, 42 66; CHECK: stocghe %r3, -524288(%r2) 67; CHECK: br %r14 68 %ptr = getelementptr i64, i64 *%base, i64 -65536 69 %cond = icmp ult i32 %limit, 42 70 %orig = load i64, i64 *%ptr 71 %res = select i1 %cond, i64 %orig, i64 %alt 72 store i64 %res, i64 *%ptr 73 ret void 74} 75 76; Check the next doubleword down, with the same comments as f4. 77define void @f6(i64 *%base, i64 %alt, i32 %limit) { 78; CHECK-LABEL: f6: 79; CHECK: agfi %r2, -524296 80; CHECK: clfi %r4, 42 81; CHECK: stocghe %r3, 0(%r2) 82; CHECK: br %r14 83 %ptr = getelementptr i64, i64 *%base, i64 -65537 84 %cond = icmp ult i32 %limit, 42 85 %orig = load i64, i64 *%ptr 86 %res = select i1 %cond, i64 %orig, i64 %alt 87 store i64 %res, i64 *%ptr 88 ret void 89} 90 91; Try a frame index base. 92define void @f7(i64 %alt, i32 %limit) { 93; CHECK-LABEL: f7: 94; CHECK: brasl %r14, foo@PLT 95; CHECK: stocghe {{%r[0-9]+}}, {{[0-9]+}}(%r15) 96; CHECK: brasl %r14, foo@PLT 97; CHECK: br %r14 98 %ptr = alloca i64 99 call void @foo(i64 *%ptr) 100 %cond = icmp ult i32 %limit, 42 101 %orig = load i64, i64 *%ptr 102 %res = select i1 %cond, i64 %orig, i64 %alt 103 store i64 %res, i64 *%ptr 104 call void @foo(i64 *%ptr) 105 ret void 106} 107 108; Test that conditionally-executed stores do not use STOC, since STOC 109; is allowed to trap even when the condition is false. 110define void @f8(i64 %a, i64 %b, i64 *%dest) { 111; CHECK-LABEL: f8: 112; CHECK-NOT: stocg %r3, 0(%r4) 113; CHECK: br %r14 114entry: 115 %cmp = icmp ule i64 %a, %b 116 br i1 %cmp, label %store, label %exit 117 118store: 119 store i64 %b, i64 *%dest 120 br label %exit 121 122exit: 123 ret void 124} 125