1; Test f32 conditional stores that are presented as selects. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5declare void @foo(float *) 6 7; Test with the loaded value first. 8define void @f1(float *%ptr, float %alt, i32 %limit) { 9; CHECK-LABEL: f1: 10; CHECK-NOT: %r2 11; CHECK: jl [[LABEL:[^ ]*]] 12; CHECK-NOT: %r2 13; CHECK: ste %f0, 0(%r2) 14; CHECK: [[LABEL]]: 15; CHECK: br %r14 16 %cond = icmp ult i32 %limit, 420 17 %orig = load float , float *%ptr 18 %res = select i1 %cond, float %orig, float %alt 19 store float %res, float *%ptr 20 ret void 21} 22 23; ...and with the loaded value second 24define void @f2(float *%ptr, float %alt, i32 %limit) { 25; CHECK-LABEL: f2: 26; CHECK-NOT: %r2 27; CHECK: jhe [[LABEL:[^ ]*]] 28; CHECK-NOT: %r2 29; CHECK: ste %f0, 0(%r2) 30; CHECK: [[LABEL]]: 31; CHECK: br %r14 32 %cond = icmp ult i32 %limit, 420 33 %orig = load float , float *%ptr 34 %res = select i1 %cond, float %alt, float %orig 35 store float %res, float *%ptr 36 ret void 37} 38 39; Check the high end of the aligned STE range. 40define void @f3(float *%base, float %alt, i32 %limit) { 41; CHECK-LABEL: f3: 42; CHECK-NOT: %r2 43; CHECK: jl [[LABEL:[^ ]*]] 44; CHECK-NOT: %r2 45; CHECK: ste %f0, 4092(%r2) 46; CHECK: [[LABEL]]: 47; CHECK: br %r14 48 %ptr = getelementptr float, float *%base, i64 1023 49 %cond = icmp ult i32 %limit, 420 50 %orig = load float , float *%ptr 51 %res = select i1 %cond, float %orig, float %alt 52 store float %res, float *%ptr 53 ret void 54} 55 56; Check the next word up, which should use STEY instead of STE. 57define void @f4(float *%base, float %alt, i32 %limit) { 58; CHECK-LABEL: f4: 59; CHECK-NOT: %r2 60; CHECK: jl [[LABEL:[^ ]*]] 61; CHECK-NOT: %r2 62; CHECK: stey %f0, 4096(%r2) 63; CHECK: [[LABEL]]: 64; CHECK: br %r14 65 %ptr = getelementptr float, float *%base, i64 1024 66 %cond = icmp ult i32 %limit, 420 67 %orig = load float , float *%ptr 68 %res = select i1 %cond, float %orig, float %alt 69 store float %res, float *%ptr 70 ret void 71} 72 73; Check the high end of the aligned STEY range. 74define void @f5(float *%base, float %alt, i32 %limit) { 75; CHECK-LABEL: f5: 76; CHECK-NOT: %r2 77; CHECK: jl [[LABEL:[^ ]*]] 78; CHECK-NOT: %r2 79; CHECK: stey %f0, 524284(%r2) 80; CHECK: [[LABEL]]: 81; CHECK: br %r14 82 %ptr = getelementptr float, float *%base, i64 131071 83 %cond = icmp ult i32 %limit, 420 84 %orig = load float , float *%ptr 85 %res = select i1 %cond, float %orig, float %alt 86 store float %res, float *%ptr 87 ret void 88} 89 90; Check the next word up, which needs separate address logic. 91; Other sequences besides this one would be OK. 92define void @f6(float *%base, float %alt, i32 %limit) { 93; CHECK-LABEL: f6: 94; CHECK-NOT: %r2 95; CHECK: jl [[LABEL:[^ ]*]] 96; CHECK-NOT: %r2 97; CHECK: agfi %r2, 524288 98; CHECK: ste %f0, 0(%r2) 99; CHECK: [[LABEL]]: 100; CHECK: br %r14 101 %ptr = getelementptr float, float *%base, i64 131072 102 %cond = icmp ult i32 %limit, 420 103 %orig = load float , float *%ptr 104 %res = select i1 %cond, float %orig, float %alt 105 store float %res, float *%ptr 106 ret void 107} 108 109; Check the low end of the STEY range. 110define void @f7(float *%base, float %alt, i32 %limit) { 111; CHECK-LABEL: f7: 112; CHECK-NOT: %r2 113; CHECK: jl [[LABEL:[^ ]*]] 114; CHECK-NOT: %r2 115; CHECK: stey %f0, -524288(%r2) 116; CHECK: [[LABEL]]: 117; CHECK: br %r14 118 %ptr = getelementptr float, float *%base, i64 -131072 119 %cond = icmp ult i32 %limit, 420 120 %orig = load float , float *%ptr 121 %res = select i1 %cond, float %orig, float %alt 122 store float %res, float *%ptr 123 ret void 124} 125 126; Check the next word down, which needs separate address logic. 127; Other sequences besides this one would be OK. 128define void @f8(float *%base, float %alt, i32 %limit) { 129; CHECK-LABEL: f8: 130; CHECK-NOT: %r2 131; CHECK: jl [[LABEL:[^ ]*]] 132; CHECK-NOT: %r2 133; CHECK: agfi %r2, -524292 134; CHECK: ste %f0, 0(%r2) 135; CHECK: [[LABEL]]: 136; CHECK: br %r14 137 %ptr = getelementptr float, float *%base, i64 -131073 138 %cond = icmp ult i32 %limit, 420 139 %orig = load float , float *%ptr 140 %res = select i1 %cond, float %orig, float %alt 141 store float %res, float *%ptr 142 ret void 143} 144 145; Check that STEY allows an index. 146define void @f9(i64 %base, i64 %index, float %alt, i32 %limit) { 147; CHECK-LABEL: f9: 148; CHECK-NOT: %r2 149; CHECK: jl [[LABEL:[^ ]*]] 150; CHECK-NOT: %r2 151; CHECK: stey %f0, 4096(%r3,%r2) 152; CHECK: [[LABEL]]: 153; CHECK: br %r14 154 %add1 = add i64 %base, %index 155 %add2 = add i64 %add1, 4096 156 %ptr = inttoptr i64 %add2 to float * 157 %cond = icmp ult i32 %limit, 420 158 %orig = load float , float *%ptr 159 %res = select i1 %cond, float %orig, float %alt 160 store float %res, float *%ptr 161 ret void 162} 163 164; Check that volatile loads are not matched. 165define void @f10(float *%ptr, float %alt, i32 %limit) { 166; CHECK-LABEL: f10: 167; CHECK: le {{%f[0-5]}}, 0(%r2) 168; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]] 169; CHECK: [[LABEL]]: 170; CHECK: ste {{%f[0-5]}}, 0(%r2) 171; CHECK: br %r14 172 %cond = icmp ult i32 %limit, 420 173 %orig = load volatile float , float *%ptr 174 %res = select i1 %cond, float %orig, float %alt 175 store float %res, float *%ptr 176 ret void 177} 178 179; ...likewise stores. In this case we should have a conditional load into %f0. 180define void @f11(float *%ptr, float %alt, i32 %limit) { 181; CHECK-LABEL: f11: 182; CHECK: jhe [[LABEL:[^ ]*]] 183; CHECK: le %f0, 0(%r2) 184; CHECK: [[LABEL]]: 185; CHECK: ste %f0, 0(%r2) 186; CHECK: br %r14 187 %cond = icmp ult i32 %limit, 420 188 %orig = load float , float *%ptr 189 %res = select i1 %cond, float %orig, float %alt 190 store volatile float %res, float *%ptr 191 ret void 192} 193 194; Try a frame index base. 195define void @f12(float %alt, i32 %limit) { 196; CHECK-LABEL: f12: 197; CHECK: brasl %r14, foo@PLT 198; CHECK-NOT: %r15 199; CHECK: jl [[LABEL:[^ ]*]] 200; CHECK-NOT: %r15 201; CHECK: ste {{%f[0-9]+}}, {{[0-9]+}}(%r15) 202; CHECK: [[LABEL]]: 203; CHECK: brasl %r14, foo@PLT 204; CHECK: br %r14 205 %ptr = alloca float 206 call void @foo(float *%ptr) 207 %cond = icmp ult i32 %limit, 420 208 %orig = load float , float *%ptr 209 %res = select i1 %cond, float %orig, float %alt 210 store float %res, float *%ptr 211 call void @foo(float *%ptr) 212 ret void 213} 214