1 ; Test STOCGs that are presented as selects. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 4 5 declare void @foo(i64 *) 6 7 ; Test with the loaded value first. 8 define 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 *%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 21 define 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 *%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. 34 define 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 *%base, i64 65535 40 %cond = icmp ult i32 %limit, 42 41 %orig = load 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. 48 define 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 *%base, i64 65536 55 %cond = icmp ult i32 %limit, 42 56 %orig = load 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. 63 define 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 *%base, i64 -65536 69 %cond = icmp ult i32 %limit, 42 70 %orig = load 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. 77 define 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 *%base, i64 -65537 84 %cond = icmp ult i32 %limit, 42 85 %orig = load 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. 92 define 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 *%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. 110 define void @f8(i64 %a, i64 %b, i64 *%dest) { 111 ; CHECK-LABEL: f8: 112 ; CHECK-NOT: stocg %r3, 0(%r4) 113 ; CHECK: br %r14 114 entry: 115 %cmp = icmp ule i64 %a, %b 116 br i1 %cmp, label %store, label %exit 117 118 store: 119 store i64 %b, i64 *%dest 120 br label %exit 121 122 exit: 123 ret void 124 } 125