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