1; Test the use of TM and TMY. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 4 5@g = global i32 0 6 7; Check a simple branching use of TM. 8define void @f1(i8 *%src) { 9; CHECK-LABEL: f1: 10; CHECK: tm 0(%r2), 1 11; CHECK: ber %r14 12; CHECK: br %r14 13entry: 14 %byte = load i8, i8 *%src 15 %and = and i8 %byte, 1 16 %cmp = icmp eq i8 %and, 0 17 br i1 %cmp, label %exit, label %store 18 19store: 20 store i32 1, i32 *@g 21 br label %exit 22 23exit: 24 ret void 25} 26 27 28; Check that we do not fold across an aliasing store. 29define void @f2(i8 *%src) { 30; CHECK-LABEL: f2: 31; CHECK: tm 0(%r2), 1 32; CHECK: mvi 0(%r2), 0 33; CHECK: ber %r14 34; CHECK: br %r14 35entry: 36 %byte = load i8, i8 *%src 37 store i8 0, i8 *%src 38 %and = and i8 %byte, 1 39 %cmp = icmp eq i8 %and, 0 40 br i1 %cmp, label %exit, label %store 41 42store: 43 store i32 1, i32 *@g 44 br label %exit 45 46exit: 47 ret void 48} 49 50; Check a simple select-based use of TM. 51define double @f3(i8 *%src, double %a, double %b) { 52; CHECK-LABEL: f3: 53; CHECK: tm 0(%r2), 1 54; CHECK: je {{\.L.*}} 55; CHECK: br %r14 56 %byte = load i8, i8 *%src 57 %and = and i8 %byte, 1 58 %cmp = icmp eq i8 %and, 0 59 %res = select i1 %cmp, double %b, double %a 60 ret double %res 61} 62 63; Check that we do not fold across an aliasing store. 64define double @f4(i8 *%src, double %a, double %b) { 65; CHECK-LABEL: f4: 66; CHECK: tm 0(%r2), 1 67; CHECK: je {{\.L.*}} 68; CHECK: mvi 0(%r2), 0 69; CHECK: br %r14 70 %byte = load i8, i8 *%src 71 %and = and i8 %byte, 1 72 %cmp = icmp eq i8 %and, 0 73 %res = select i1 %cmp, double %b, double %a 74 store i8 0, i8 *%src 75 ret double %res 76} 77 78; Check an inequality check. 79define double @f5(i8 *%src, double %a, double %b) { 80; CHECK-LABEL: f5: 81; CHECK: tm 0(%r2), 1 82; CHECK: jne {{\.L.*}} 83; CHECK: br %r14 84 %byte = load i8, i8 *%src 85 %and = and i8 %byte, 1 86 %cmp = icmp ne i8 %and, 0 87 %res = select i1 %cmp, double %b, double %a 88 ret double %res 89} 90 91; Check that we can also use TM for equality comparisons with the mask. 92define double @f6(i8 *%src, double %a, double %b) { 93; CHECK-LABEL: f6: 94; CHECK: tm 0(%r2), 254 95; CHECK: jo {{\.L.*}} 96; CHECK: br %r14 97 %byte = load i8, i8 *%src 98 %and = and i8 %byte, 254 99 %cmp = icmp eq i8 %and, 254 100 %res = select i1 %cmp, double %b, double %a 101 ret double %res 102} 103 104; Check inequality comparisons with the mask. 105define double @f7(i8 *%src, double %a, double %b) { 106; CHECK-LABEL: f7: 107; CHECK: tm 0(%r2), 254 108; CHECK: jno {{\.L.*}} 109; CHECK: br %r14 110 %byte = load i8, i8 *%src 111 %and = and i8 %byte, 254 112 %cmp = icmp ne i8 %and, 254 113 %res = select i1 %cmp, double %b, double %a 114 ret double %res 115} 116 117; Check that we do not use the memory TM instruction when CC is being tested 118; for 2. 119define double @f8(i8 *%src, double %a, double %b) { 120; CHECK-LABEL: f8: 121; CHECK: llc [[REG:%r[0-5]]], 0(%r2) 122; CHECK: tmll [[REG]], 3 123; CHECK: jh {{\.L.*}} 124; CHECK: br %r14 125 %byte = load i8, i8 *%src 126 %and = and i8 %byte, 3 127 %cmp = icmp eq i8 %and, 2 128 %res = select i1 %cmp, double %b, double %a 129 ret double %res 130} 131 132; ...likewise 1. 133define double @f9(i8 *%src, double %a, double %b) { 134; CHECK-LABEL: f9: 135; CHECK: llc [[REG:%r[0-5]]], 0(%r2) 136; CHECK: tmll [[REG]], 3 137; CHECK: jl {{\.L.*}} 138; CHECK: br %r14 139 %byte = load i8, i8 *%src 140 %and = and i8 %byte, 3 141 %cmp = icmp eq i8 %and, 1 142 %res = select i1 %cmp, double %b, double %a 143 ret double %res 144} 145 146; Check the high end of the TM range. 147define double @f10(i8 *%src, double %a, double %b) { 148; CHECK-LABEL: f10: 149; CHECK: tm 4095(%r2), 1 150; CHECK: je {{\.L.*}} 151; CHECK: br %r14 152 %ptr = getelementptr i8, i8 *%src, i64 4095 153 %byte = load i8, i8 *%ptr 154 %and = and i8 %byte, 1 155 %cmp = icmp eq i8 %and, 0 156 %res = select i1 %cmp, double %b, double %a 157 ret double %res 158} 159 160; Check the low end of the positive TMY range. 161define double @f11(i8 *%src, double %a, double %b) { 162; CHECK-LABEL: f11: 163; CHECK: tmy 4096(%r2), 1 164; CHECK: je {{\.L.*}} 165; CHECK: br %r14 166 %ptr = getelementptr i8, i8 *%src, i64 4096 167 %byte = load i8, i8 *%ptr 168 %and = and i8 %byte, 1 169 %cmp = icmp eq i8 %and, 0 170 %res = select i1 %cmp, double %b, double %a 171 ret double %res 172} 173 174; Check the high end of the TMY range. 175define double @f12(i8 *%src, double %a, double %b) { 176; CHECK-LABEL: f12: 177; CHECK: tmy 524287(%r2), 1 178; CHECK: je {{\.L.*}} 179; CHECK: br %r14 180 %ptr = getelementptr i8, i8 *%src, i64 524287 181 %byte = load i8, i8 *%ptr 182 %and = and i8 %byte, 1 183 %cmp = icmp eq i8 %and, 0 184 %res = select i1 %cmp, double %b, double %a 185 ret double %res 186} 187 188; Check the next byte up, which needs separate address logic. 189define double @f13(i8 *%src, double %a, double %b) { 190; CHECK-LABEL: f13: 191; CHECK: agfi %r2, 524288 192; CHECK: tm 0(%r2), 1 193; CHECK: je {{\.L.*}} 194; CHECK: br %r14 195 %ptr = getelementptr i8, i8 *%src, i64 524288 196 %byte = load i8, i8 *%ptr 197 %and = and i8 %byte, 1 198 %cmp = icmp eq i8 %and, 0 199 %res = select i1 %cmp, double %b, double %a 200 ret double %res 201} 202 203; Check the low end of the TMY range. 204define double @f14(i8 *%src, double %a, double %b) { 205; CHECK-LABEL: f14: 206; CHECK: tmy -524288(%r2), 1 207; CHECK: je {{\.L.*}} 208; CHECK: br %r14 209 %ptr = getelementptr i8, i8 *%src, i64 -524288 210 %byte = load i8, i8 *%ptr 211 %and = and i8 %byte, 1 212 %cmp = icmp eq i8 %and, 0 213 %res = select i1 %cmp, double %b, double %a 214 ret double %res 215} 216 217; Check the next byte down, which needs separate address logic. 218define double @f15(i8 *%src, double %a, double %b) { 219; CHECK-LABEL: f15: 220; CHECK: agfi %r2, -524289 221; CHECK: tm 0(%r2), 1 222; CHECK: je {{\.L.*}} 223; CHECK: br %r14 224 %ptr = getelementptr i8, i8 *%src, i64 -524289 225 %byte = load i8, i8 *%ptr 226 %and = and i8 %byte, 1 227 %cmp = icmp eq i8 %and, 0 228 %res = select i1 %cmp, double %b, double %a 229 ret double %res 230} 231 232; Check that TM(Y) does not allow an index 233define double @f16(i8 *%src, i64 %index, double %a, double %b) { 234; CHECK-LABEL: f16: 235; CHECK: tm 0({{%r[1-5]}}), 1 236; CHECK: je {{\.L.*}} 237; CHECK: br %r14 238 %ptr = getelementptr i8, i8 *%src, i64 %index 239 %byte = load i8, i8 *%ptr 240 %and = and i8 %byte, 1 241 %cmp = icmp eq i8 %and, 0 242 %res = select i1 %cmp, double %b, double %a 243 ret double %res 244} 245