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