1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -slp-vectorizer -S %s | FileCheck %s 3; RUN: opt -aa-pipeline=basic-aa -passes='slp-vectorizer' -S %s | FileCheck %s 4 5target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 6target triple = "arm64-apple-ios5.0.0" 7 8define void @select_umin_8xi16(i16* %ptr, i16 %x) { 9; CHECK-LABEL: @select_umin_8xi16( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 12; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 13; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 14; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 15; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 16; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 17; CHECK-NEXT: ret void 18; 19entry: 20 %l.0 = load i16, i16* %ptr 21 %cmp.0 = icmp ult i16 %l.0, 16383 22 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 23 store i16 %s.0, i16* %ptr, align 2 24 25 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 26 %l.1 = load i16, i16* %gep.1 27 %cmp.1 = icmp ult i16 %l.1, 16383 28 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 29 store i16 %s.1, i16* %gep.1, align 2 30 31 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 32 %l.2 = load i16, i16* %gep.2 33 %cmp.2 = icmp ult i16 %l.2, 16383 34 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 35 store i16 %s.2, i16* %gep.2, align 2 36 37 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 38 %l.3 = load i16, i16* %gep.3 39 %cmp.3 = icmp ult i16 %l.3, 16383 40 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 41 store i16 %s.3, i16* %gep.3, align 2 42 43 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 44 %l.4 = load i16, i16* %gep.4 45 %cmp.4 = icmp ult i16 %l.4, 16383 46 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 47 store i16 %s.4, i16* %gep.4, align 2 48 49 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 50 %l.5 = load i16, i16* %gep.5 51 %cmp.5 = icmp ult i16 %l.5, 16383 52 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 53 store i16 %s.5, i16* %gep.5, align 2 54 55 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 56 %l.6 = load i16, i16* %gep.6 57 %cmp.6 = icmp ult i16 %l.6, 16383 58 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 59 store i16 %s.6, i16* %gep.6, align 2 60 61 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 62 %l.7 = load i16, i16* %gep.7 63 %cmp.7 = icmp ult i16 %l.7, 16383 64 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 65 store i16 %s.7, i16* %gep.7, align 2 66 ret void 67} 68 69define void @select_umin_4xi32(i32* %ptr, i32 %x) { 70; CHECK-LABEL: @select_umin_4xi32( 71; CHECK-NEXT: entry: 72; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 73; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 74; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 75; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 76; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 77; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 78; CHECK-NEXT: ret void 79; 80entry: 81 %l.0 = load i32, i32* %ptr 82 %cmp.0 = icmp ult i32 %l.0, 16383 83 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 84 store i32 %s.0, i32* %ptr, align 4 85 86 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 87 %l.1 = load i32, i32* %gep.1 88 %cmp.1 = icmp ult i32 %l.1, 16383 89 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 90 store i32 %s.1, i32* %gep.1, align 4 91 92 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 93 %l.2 = load i32, i32* %gep.2 94 %cmp.2 = icmp ult i32 %l.2, 16383 95 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 96 store i32 %s.2, i32* %gep.2, align 4 97 98 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 99 %l.3 = load i32, i32* %gep.3 100 %cmp.3 = icmp ult i32 %l.3, 16383 101 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 102 store i32 %s.3, i32* %gep.3, align 4 103 104 ret void 105} 106 107define void @select_ule_ugt_mix_4xi32(i32* %ptr, i32 %x) { 108; CHECK-LABEL: @select_ule_ugt_mix_4xi32( 109; CHECK-NEXT: entry: 110; CHECK-NEXT: [[L_0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 111; CHECK-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[L_0]], 16383 112; CHECK-NEXT: [[S_0:%.*]] = select i1 [[CMP_0]], i32 [[L_0]], i32 16383 113; CHECK-NEXT: store i32 [[S_0]], i32* [[PTR]], align 4 114; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 1 115; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[GEP_1]], align 4 116; CHECK-NEXT: [[CMP_1:%.*]] = icmp ugt i32 [[L_1]], 16383 117; CHECK-NEXT: [[S_1:%.*]] = select i1 [[CMP_1]], i32 [[L_1]], i32 16383 118; CHECK-NEXT: store i32 [[S_1]], i32* [[GEP_1]], align 4 119; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 2 120; CHECK-NEXT: [[L_2:%.*]] = load i32, i32* [[GEP_2]], align 4 121; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[L_2]], 16383 122; CHECK-NEXT: [[S_2:%.*]] = select i1 [[CMP_2]], i32 [[L_2]], i32 16383 123; CHECK-NEXT: store i32 [[S_2]], i32* [[GEP_2]], align 4 124; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 3 125; CHECK-NEXT: [[L_3:%.*]] = load i32, i32* [[GEP_3]], align 4 126; CHECK-NEXT: [[CMP_3:%.*]] = icmp ugt i32 [[L_3]], 16383 127; CHECK-NEXT: [[S_3:%.*]] = select i1 [[CMP_3]], i32 [[L_3]], i32 16383 128; CHECK-NEXT: store i32 [[S_3]], i32* [[GEP_3]], align 4 129; CHECK-NEXT: ret void 130; 131entry: 132 %l.0 = load i32, i32* %ptr 133 %cmp.0 = icmp ult i32 %l.0, 16383 134 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 135 store i32 %s.0, i32* %ptr, align 4 136 137 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 138 %l.1 = load i32, i32* %gep.1 139 %cmp.1 = icmp ugt i32 %l.1, 16383 140 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 141 store i32 %s.1, i32* %gep.1, align 4 142 143 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 144 %l.2 = load i32, i32* %gep.2 145 %cmp.2 = icmp ult i32 %l.2, 16383 146 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 147 store i32 %s.2, i32* %gep.2, align 4 148 149 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 150 %l.3 = load i32, i32* %gep.3 151 %cmp.3 = icmp ugt i32 %l.3, 16383 152 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 153 store i32 %s.3, i32* %gep.3, align 4 154 155 ret void 156} 157 158; There is no <2 x i64> version of umin, but we can efficiently lower 159; compare/select pairs with uniform predicates. 160define void @select_umin_2xi64(i64* %ptr, i64 %x) { 161; CHECK-LABEL: @select_umin_2xi64( 162; CHECK-NEXT: entry: 163; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 164; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 165; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], <i64 16383, i64 16383> 166; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 167; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 168; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 169; CHECK-NEXT: ret void 170; 171entry: 172 %l.0 = load i64, i64* %ptr 173 %cmp.0 = icmp ult i64 %l.0, 16383 174 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 175 store i64 %s.0, i64* %ptr, align 4 176 177 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 178 %l.1 = load i64, i64* %gep.1 179 %cmp.1 = icmp ult i64 %l.1, 16383 180 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 181 store i64 %s.1, i64* %gep.1, align 4 182 183 ret void 184} 185 186 187define void @select_umin_ule_8xi16(i16* %ptr, i16 %x) { 188; CHECK-LABEL: @select_umin_ule_8xi16( 189; CHECK-NEXT: entry: 190; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 191; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 192; CHECK-NEXT: [[TMP2:%.*]] = icmp ule <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 193; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 194; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 195; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 196; CHECK-NEXT: ret void 197; 198entry: 199 %l.0 = load i16, i16* %ptr 200 %cmp.0 = icmp ule i16 %l.0, 16383 201 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 202 store i16 %s.0, i16* %ptr, align 2 203 204 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 205 %l.1 = load i16, i16* %gep.1 206 %cmp.1 = icmp ule i16 %l.1, 16383 207 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 208 store i16 %s.1, i16* %gep.1, align 2 209 210 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 211 %l.2 = load i16, i16* %gep.2 212 %cmp.2 = icmp ule i16 %l.2, 16383 213 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 214 store i16 %s.2, i16* %gep.2, align 2 215 216 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 217 %l.3 = load i16, i16* %gep.3 218 %cmp.3 = icmp ule i16 %l.3, 16383 219 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 220 store i16 %s.3, i16* %gep.3, align 2 221 222 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 223 %l.4 = load i16, i16* %gep.4 224 %cmp.4 = icmp ule i16 %l.4, 16383 225 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 226 store i16 %s.4, i16* %gep.4, align 2 227 228 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 229 %l.5 = load i16, i16* %gep.5 230 %cmp.5 = icmp ule i16 %l.5, 16383 231 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 232 store i16 %s.5, i16* %gep.5, align 2 233 234 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 235 %l.6 = load i16, i16* %gep.6 236 %cmp.6 = icmp ule i16 %l.6, 16383 237 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 238 store i16 %s.6, i16* %gep.6, align 2 239 240 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 241 %l.7 = load i16, i16* %gep.7 242 %cmp.7 = icmp ule i16 %l.7, 16383 243 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 244 store i16 %s.7, i16* %gep.7, align 2 245 ret void 246} 247 248define void @select_umin_ule_4xi32(i32* %ptr, i32 %x) { 249; CHECK-LABEL: @select_umin_ule_4xi32( 250; CHECK-NEXT: entry: 251; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 252; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 253; CHECK-NEXT: [[TMP2:%.*]] = icmp ule <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 254; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 255; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 256; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 257; CHECK-NEXT: ret void 258; 259entry: 260 %l.0 = load i32, i32* %ptr 261 %cmp.0 = icmp ule i32 %l.0, 16383 262 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 263 store i32 %s.0, i32* %ptr, align 4 264 265 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 266 %l.1 = load i32, i32* %gep.1 267 %cmp.1 = icmp ule i32 %l.1, 16383 268 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 269 store i32 %s.1, i32* %gep.1, align 4 270 271 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 272 %l.2 = load i32, i32* %gep.2 273 %cmp.2 = icmp ule i32 %l.2, 16383 274 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 275 store i32 %s.2, i32* %gep.2, align 4 276 277 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 278 %l.3 = load i32, i32* %gep.3 279 %cmp.3 = icmp ule i32 %l.3, 16383 280 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 281 store i32 %s.3, i32* %gep.3, align 4 282 283 ret void 284} 285 286; There is no <2 x i64> version of umin, but we can efficiently lower 287; compare/select pairs with uniform predicates. 288define void @select_umin_ule_2xi64(i64* %ptr, i64 %x) { 289; CHECK-LABEL: @select_umin_ule_2xi64( 290; CHECK-NEXT: entry: 291; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 292; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 293; CHECK-NEXT: [[TMP2:%.*]] = icmp ule <2 x i64> [[TMP1]], <i64 16383, i64 16383> 294; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 295; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 296; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 297; CHECK-NEXT: ret void 298; 299entry: 300 %l.0 = load i64, i64* %ptr 301 %cmp.0 = icmp ule i64 %l.0, 16383 302 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 303 store i64 %s.0, i64* %ptr, align 4 304 305 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 306 %l.1 = load i64, i64* %gep.1 307 %cmp.1 = icmp ule i64 %l.1, 16383 308 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 309 store i64 %s.1, i64* %gep.1, align 4 310 311 ret void 312} 313 314define void @select_smin_8xi16(i16* %ptr, i16 %x) { 315; CHECK-LABEL: @select_smin_8xi16( 316; CHECK-NEXT: entry: 317; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 318; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 319; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 320; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 321; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 322; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 323; CHECK-NEXT: ret void 324; 325entry: 326 %l.0 = load i16, i16* %ptr 327 %cmp.0 = icmp slt i16 %l.0, 16383 328 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 329 store i16 %s.0, i16* %ptr, align 2 330 331 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 332 %l.1 = load i16, i16* %gep.1 333 %cmp.1 = icmp slt i16 %l.1, 16383 334 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 335 store i16 %s.1, i16* %gep.1, align 2 336 337 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 338 %l.2 = load i16, i16* %gep.2 339 %cmp.2 = icmp slt i16 %l.2, 16383 340 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 341 store i16 %s.2, i16* %gep.2, align 2 342 343 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 344 %l.3 = load i16, i16* %gep.3 345 %cmp.3 = icmp slt i16 %l.3, 16383 346 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 347 store i16 %s.3, i16* %gep.3, align 2 348 349 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 350 %l.4 = load i16, i16* %gep.4 351 %cmp.4 = icmp slt i16 %l.4, 16383 352 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 353 store i16 %s.4, i16* %gep.4, align 2 354 355 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 356 %l.5 = load i16, i16* %gep.5 357 %cmp.5 = icmp slt i16 %l.5, 16383 358 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 359 store i16 %s.5, i16* %gep.5, align 2 360 361 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 362 %l.6 = load i16, i16* %gep.6 363 %cmp.6 = icmp slt i16 %l.6, 16383 364 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 365 store i16 %s.6, i16* %gep.6, align 2 366 367 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 368 %l.7 = load i16, i16* %gep.7 369 %cmp.7 = icmp slt i16 %l.7, 16383 370 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 371 store i16 %s.7, i16* %gep.7, align 2 372 ret void 373} 374 375define void @select_smin_4xi32(i32* %ptr, i32 %x) { 376; CHECK-LABEL: @select_smin_4xi32( 377; CHECK-NEXT: entry: 378; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 379; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 380; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 381; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 382; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 383; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 384; CHECK-NEXT: ret void 385; 386entry: 387 %l.0 = load i32, i32* %ptr 388 %cmp.0 = icmp slt i32 %l.0, 16383 389 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 390 store i32 %s.0, i32* %ptr, align 4 391 392 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 393 %l.1 = load i32, i32* %gep.1 394 %cmp.1 = icmp slt i32 %l.1, 16383 395 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 396 store i32 %s.1, i32* %gep.1, align 4 397 398 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 399 %l.2 = load i32, i32* %gep.2 400 %cmp.2 = icmp slt i32 %l.2, 16383 401 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 402 store i32 %s.2, i32* %gep.2, align 4 403 404 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 405 %l.3 = load i32, i32* %gep.3 406 %cmp.3 = icmp slt i32 %l.3, 16383 407 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 408 store i32 %s.3, i32* %gep.3, align 4 409 410 ret void 411} 412 413; There is no <2 x i64> version of smin, but we can efficiently lower 414; compare/select pairs with uniform predicates. 415define void @select_smin_2xi64(i64* %ptr, i64 %x) { 416; CHECK-LABEL: @select_smin_2xi64( 417; CHECK-NEXT: entry: 418; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 419; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 420; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i64> [[TMP1]], <i64 16383, i64 16383> 421; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 422; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 423; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 424; CHECK-NEXT: ret void 425; 426entry: 427 %l.0 = load i64, i64* %ptr 428 %cmp.0 = icmp slt i64 %l.0, 16383 429 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 430 store i64 %s.0, i64* %ptr, align 4 431 432 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 433 %l.1 = load i64, i64* %gep.1 434 %cmp.1 = icmp slt i64 %l.1, 16383 435 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 436 store i64 %s.1, i64* %gep.1, align 4 437 438 ret void 439} 440 441define void @select_smin_sle_8xi16(i16* %ptr, i16 %x) { 442; CHECK-LABEL: @select_smin_sle_8xi16( 443; CHECK-NEXT: entry: 444; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 445; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 446; CHECK-NEXT: [[TMP2:%.*]] = icmp sle <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 447; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 448; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 449; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 450; CHECK-NEXT: ret void 451; 452entry: 453 %l.0 = load i16, i16* %ptr 454 %cmp.0 = icmp sle i16 %l.0, 16383 455 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 456 store i16 %s.0, i16* %ptr, align 2 457 458 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 459 %l.1 = load i16, i16* %gep.1 460 %cmp.1 = icmp sle i16 %l.1, 16383 461 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 462 store i16 %s.1, i16* %gep.1, align 2 463 464 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 465 %l.2 = load i16, i16* %gep.2 466 %cmp.2 = icmp sle i16 %l.2, 16383 467 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 468 store i16 %s.2, i16* %gep.2, align 2 469 470 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 471 %l.3 = load i16, i16* %gep.3 472 %cmp.3 = icmp sle i16 %l.3, 16383 473 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 474 store i16 %s.3, i16* %gep.3, align 2 475 476 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 477 %l.4 = load i16, i16* %gep.4 478 %cmp.4 = icmp sle i16 %l.4, 16383 479 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 480 store i16 %s.4, i16* %gep.4, align 2 481 482 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 483 %l.5 = load i16, i16* %gep.5 484 %cmp.5 = icmp sle i16 %l.5, 16383 485 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 486 store i16 %s.5, i16* %gep.5, align 2 487 488 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 489 %l.6 = load i16, i16* %gep.6 490 %cmp.6 = icmp sle i16 %l.6, 16383 491 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 492 store i16 %s.6, i16* %gep.6, align 2 493 494 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 495 %l.7 = load i16, i16* %gep.7 496 %cmp.7 = icmp sle i16 %l.7, 16383 497 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 498 store i16 %s.7, i16* %gep.7, align 2 499 ret void 500} 501 502define void @select_smin_sle_4xi32(i32* %ptr, i32 %x) { 503; CHECK-LABEL: @select_smin_sle_4xi32( 504; CHECK-NEXT: entry: 505; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 506; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 507; CHECK-NEXT: [[TMP2:%.*]] = icmp sle <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 508; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 509; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 510; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 511; CHECK-NEXT: ret void 512; 513entry: 514 %l.0 = load i32, i32* %ptr 515 %cmp.0 = icmp sle i32 %l.0, 16383 516 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 517 store i32 %s.0, i32* %ptr, align 4 518 519 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 520 %l.1 = load i32, i32* %gep.1 521 %cmp.1 = icmp sle i32 %l.1, 16383 522 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 523 store i32 %s.1, i32* %gep.1, align 4 524 525 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 526 %l.2 = load i32, i32* %gep.2 527 %cmp.2 = icmp sle i32 %l.2, 16383 528 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 529 store i32 %s.2, i32* %gep.2, align 4 530 531 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 532 %l.3 = load i32, i32* %gep.3 533 %cmp.3 = icmp sle i32 %l.3, 16383 534 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 535 store i32 %s.3, i32* %gep.3, align 4 536 537 ret void 538} 539 540; There is no <2 x i64> version of smin, but we can efficiently lower 541; compare/select pairs with uniform predicates. 542define void @select_smin_sle_2xi64(i64* %ptr, i64 %x) { 543; CHECK-LABEL: @select_smin_sle_2xi64( 544; CHECK-NEXT: entry: 545; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 546; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 547; CHECK-NEXT: [[TMP2:%.*]] = icmp sle <2 x i64> [[TMP1]], <i64 16383, i64 16383> 548; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 549; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 550; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 551; CHECK-NEXT: ret void 552; 553entry: 554 %l.0 = load i64, i64* %ptr 555 %cmp.0 = icmp sle i64 %l.0, 16383 556 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 557 store i64 %s.0, i64* %ptr, align 4 558 559 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 560 %l.1 = load i64, i64* %gep.1 561 %cmp.1 = icmp sle i64 %l.1, 16383 562 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 563 store i64 %s.1, i64* %gep.1, align 4 564 565 ret void 566} 567define void @select_umax_8xi16(i16* %ptr, i16 %x) { 568; CHECK-LABEL: @select_umax_8xi16( 569; CHECK-NEXT: entry: 570; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 571; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 572; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 573; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 574; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 575; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 576; CHECK-NEXT: ret void 577; 578entry: 579 %l.0 = load i16, i16* %ptr 580 %cmp.0 = icmp ugt i16 %l.0, 16383 581 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 582 store i16 %s.0, i16* %ptr, align 2 583 584 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 585 %l.1 = load i16, i16* %gep.1 586 %cmp.1 = icmp ugt i16 %l.1, 16383 587 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 588 store i16 %s.1, i16* %gep.1, align 2 589 590 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 591 %l.2 = load i16, i16* %gep.2 592 %cmp.2 = icmp ugt i16 %l.2, 16383 593 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 594 store i16 %s.2, i16* %gep.2, align 2 595 596 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 597 %l.3 = load i16, i16* %gep.3 598 %cmp.3 = icmp ugt i16 %l.3, 16383 599 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 600 store i16 %s.3, i16* %gep.3, align 2 601 602 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 603 %l.4 = load i16, i16* %gep.4 604 %cmp.4 = icmp ugt i16 %l.4, 16383 605 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 606 store i16 %s.4, i16* %gep.4, align 2 607 608 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 609 %l.5 = load i16, i16* %gep.5 610 %cmp.5 = icmp ugt i16 %l.5, 16383 611 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 612 store i16 %s.5, i16* %gep.5, align 2 613 614 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 615 %l.6 = load i16, i16* %gep.6 616 %cmp.6 = icmp ugt i16 %l.6, 16383 617 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 618 store i16 %s.6, i16* %gep.6, align 2 619 620 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 621 %l.7 = load i16, i16* %gep.7 622 %cmp.7 = icmp ugt i16 %l.7, 16383 623 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 624 store i16 %s.7, i16* %gep.7, align 2 625 ret void 626} 627 628define void @select_umax_4xi32(i32* %ptr, i32 %x) { 629; CHECK-LABEL: @select_umax_4xi32( 630; CHECK-NEXT: entry: 631; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 632; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 633; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 634; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 635; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 636; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 637; CHECK-NEXT: ret void 638; 639entry: 640 %l.0 = load i32, i32* %ptr 641 %cmp.0 = icmp ugt i32 %l.0, 16383 642 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 643 store i32 %s.0, i32* %ptr, align 4 644 645 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 646 %l.1 = load i32, i32* %gep.1 647 %cmp.1 = icmp ugt i32 %l.1, 16383 648 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 649 store i32 %s.1, i32* %gep.1, align 4 650 651 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 652 %l.2 = load i32, i32* %gep.2 653 %cmp.2 = icmp ugt i32 %l.2, 16383 654 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 655 store i32 %s.2, i32* %gep.2, align 4 656 657 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 658 %l.3 = load i32, i32* %gep.3 659 %cmp.3 = icmp ugt i32 %l.3, 16383 660 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 661 store i32 %s.3, i32* %gep.3, align 4 662 663 ret void 664} 665 666; There is no <2 x i64> version of umax, but we can efficiently lower 667; compare/select pairs with uniform predicates. 668define void @select_umax_2xi64(i64* %ptr, i64 %x) { 669; CHECK-LABEL: @select_umax_2xi64( 670; CHECK-NEXT: entry: 671; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 672; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 673; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt <2 x i64> [[TMP1]], <i64 16383, i64 16383> 674; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 675; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 676; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 677; CHECK-NEXT: ret void 678; 679entry: 680 %l.0 = load i64, i64* %ptr 681 %cmp.0 = icmp ugt i64 %l.0, 16383 682 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 683 store i64 %s.0, i64* %ptr, align 4 684 685 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 686 %l.1 = load i64, i64* %gep.1 687 %cmp.1 = icmp ugt i64 %l.1, 16383 688 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 689 store i64 %s.1, i64* %gep.1, align 4 690 691 ret void 692} 693 694define void @select_umax_uge_8xi16(i16* %ptr, i16 %x) { 695; CHECK-LABEL: @select_umax_uge_8xi16( 696; CHECK-NEXT: entry: 697; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 698; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 699; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 700; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 701; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 702; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 703; CHECK-NEXT: ret void 704; 705entry: 706 %l.0 = load i16, i16* %ptr 707 %cmp.0 = icmp uge i16 %l.0, 16383 708 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 709 store i16 %s.0, i16* %ptr, align 2 710 711 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 712 %l.1 = load i16, i16* %gep.1 713 %cmp.1 = icmp uge i16 %l.1, 16383 714 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 715 store i16 %s.1, i16* %gep.1, align 2 716 717 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 718 %l.2 = load i16, i16* %gep.2 719 %cmp.2 = icmp uge i16 %l.2, 16383 720 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 721 store i16 %s.2, i16* %gep.2, align 2 722 723 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 724 %l.3 = load i16, i16* %gep.3 725 %cmp.3 = icmp uge i16 %l.3, 16383 726 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 727 store i16 %s.3, i16* %gep.3, align 2 728 729 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 730 %l.4 = load i16, i16* %gep.4 731 %cmp.4 = icmp uge i16 %l.4, 16383 732 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 733 store i16 %s.4, i16* %gep.4, align 2 734 735 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 736 %l.5 = load i16, i16* %gep.5 737 %cmp.5 = icmp uge i16 %l.5, 16383 738 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 739 store i16 %s.5, i16* %gep.5, align 2 740 741 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 742 %l.6 = load i16, i16* %gep.6 743 %cmp.6 = icmp uge i16 %l.6, 16383 744 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 745 store i16 %s.6, i16* %gep.6, align 2 746 747 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 748 %l.7 = load i16, i16* %gep.7 749 %cmp.7 = icmp uge i16 %l.7, 16383 750 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 751 store i16 %s.7, i16* %gep.7, align 2 752 ret void 753} 754 755define void @select_umax_uge_4xi32(i32* %ptr, i32 %x) { 756; CHECK-LABEL: @select_umax_uge_4xi32( 757; CHECK-NEXT: entry: 758; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 759; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 760; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 761; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 762; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 763; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 764; CHECK-NEXT: ret void 765; 766entry: 767 %l.0 = load i32, i32* %ptr 768 %cmp.0 = icmp uge i32 %l.0, 16383 769 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 770 store i32 %s.0, i32* %ptr, align 4 771 772 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 773 %l.1 = load i32, i32* %gep.1 774 %cmp.1 = icmp uge i32 %l.1, 16383 775 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 776 store i32 %s.1, i32* %gep.1, align 4 777 778 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 779 %l.2 = load i32, i32* %gep.2 780 %cmp.2 = icmp uge i32 %l.2, 16383 781 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 782 store i32 %s.2, i32* %gep.2, align 4 783 784 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 785 %l.3 = load i32, i32* %gep.3 786 %cmp.3 = icmp uge i32 %l.3, 16383 787 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 788 store i32 %s.3, i32* %gep.3, align 4 789 790 ret void 791} 792 793; There is no <2 x i64> version of umax, but we can efficiently lower 794; compare/select pairs with uniform predicates. 795define void @select_umax_uge_2xi64(i64* %ptr, i64 %x) { 796; CHECK-LABEL: @select_umax_uge_2xi64( 797; CHECK-NEXT: entry: 798; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 799; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 800; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], <i64 16383, i64 16383> 801; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 802; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 803; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 804; CHECK-NEXT: ret void 805; 806entry: 807 %l.0 = load i64, i64* %ptr 808 %cmp.0 = icmp uge i64 %l.0, 16383 809 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 810 store i64 %s.0, i64* %ptr, align 4 811 812 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 813 %l.1 = load i64, i64* %gep.1 814 %cmp.1 = icmp uge i64 %l.1, 16383 815 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 816 store i64 %s.1, i64* %gep.1, align 4 817 818 ret void 819} 820 821define void @select_smax_8xi16(i16* %ptr, i16 %x) { 822; CHECK-LABEL: @select_smax_8xi16( 823; CHECK-NEXT: entry: 824; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 825; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 826; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 827; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 828; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 829; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 830; CHECK-NEXT: ret void 831; 832entry: 833 %l.0 = load i16, i16* %ptr 834 %cmp.0 = icmp sgt i16 %l.0, 16383 835 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 836 store i16 %s.0, i16* %ptr, align 2 837 838 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 839 %l.1 = load i16, i16* %gep.1 840 %cmp.1 = icmp sgt i16 %l.1, 16383 841 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 842 store i16 %s.1, i16* %gep.1, align 2 843 844 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 845 %l.2 = load i16, i16* %gep.2 846 %cmp.2 = icmp sgt i16 %l.2, 16383 847 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 848 store i16 %s.2, i16* %gep.2, align 2 849 850 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 851 %l.3 = load i16, i16* %gep.3 852 %cmp.3 = icmp sgt i16 %l.3, 16383 853 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 854 store i16 %s.3, i16* %gep.3, align 2 855 856 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 857 %l.4 = load i16, i16* %gep.4 858 %cmp.4 = icmp sgt i16 %l.4, 16383 859 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 860 store i16 %s.4, i16* %gep.4, align 2 861 862 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 863 %l.5 = load i16, i16* %gep.5 864 %cmp.5 = icmp sgt i16 %l.5, 16383 865 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 866 store i16 %s.5, i16* %gep.5, align 2 867 868 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 869 %l.6 = load i16, i16* %gep.6 870 %cmp.6 = icmp sgt i16 %l.6, 16383 871 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 872 store i16 %s.6, i16* %gep.6, align 2 873 874 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 875 %l.7 = load i16, i16* %gep.7 876 %cmp.7 = icmp sgt i16 %l.7, 16383 877 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 878 store i16 %s.7, i16* %gep.7, align 2 879 ret void 880} 881 882define void @select_smax_4xi32(i32* %ptr, i32 %x) { 883; CHECK-LABEL: @select_smax_4xi32( 884; CHECK-NEXT: entry: 885; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 886; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 887; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 888; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 889; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 890; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 891; CHECK-NEXT: ret void 892; 893entry: 894 %l.0 = load i32, i32* %ptr 895 %cmp.0 = icmp sgt i32 %l.0, 16383 896 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 897 store i32 %s.0, i32* %ptr, align 4 898 899 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 900 %l.1 = load i32, i32* %gep.1 901 %cmp.1 = icmp sgt i32 %l.1, 16383 902 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 903 store i32 %s.1, i32* %gep.1, align 4 904 905 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 906 %l.2 = load i32, i32* %gep.2 907 %cmp.2 = icmp sgt i32 %l.2, 16383 908 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 909 store i32 %s.2, i32* %gep.2, align 4 910 911 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 912 %l.3 = load i32, i32* %gep.3 913 %cmp.3 = icmp sgt i32 %l.3, 16383 914 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 915 store i32 %s.3, i32* %gep.3, align 4 916 917 ret void 918} 919 920; There is no <2 x i64> version of smax, but we can efficiently lower 921; compare/select pairs with uniform predicates. 922define void @select_smax_2xi64(i64* %ptr, i64 %x) { 923; CHECK-LABEL: @select_smax_2xi64( 924; CHECK-NEXT: entry: 925; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 926; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 927; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 16383, i64 16383> 928; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 929; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 930; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 931; CHECK-NEXT: ret void 932; 933entry: 934 %l.0 = load i64, i64* %ptr 935 %cmp.0 = icmp sgt i64 %l.0, 16383 936 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 937 store i64 %s.0, i64* %ptr, align 4 938 939 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 940 %l.1 = load i64, i64* %gep.1 941 %cmp.1 = icmp sgt i64 %l.1, 16383 942 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 943 store i64 %s.1, i64* %gep.1, align 4 944 945 ret void 946} 947 948 949define void @select_smax_sge_8xi16(i16* %ptr, i16 %x) { 950; CHECK-LABEL: @select_smax_sge_8xi16( 951; CHECK-NEXT: entry: 952; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>* 953; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2 954; CHECK-NEXT: [[TMP2:%.*]] = icmp sge <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 955; CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383> 956; CHECK-NEXT: [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>* 957; CHECK-NEXT: store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2 958; CHECK-NEXT: ret void 959; 960entry: 961 %l.0 = load i16, i16* %ptr 962 %cmp.0 = icmp sge i16 %l.0, 16383 963 %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383 964 store i16 %s.0, i16* %ptr, align 2 965 966 %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1 967 %l.1 = load i16, i16* %gep.1 968 %cmp.1 = icmp sge i16 %l.1, 16383 969 %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383 970 store i16 %s.1, i16* %gep.1, align 2 971 972 %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2 973 %l.2 = load i16, i16* %gep.2 974 %cmp.2 = icmp sge i16 %l.2, 16383 975 %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383 976 store i16 %s.2, i16* %gep.2, align 2 977 978 %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3 979 %l.3 = load i16, i16* %gep.3 980 %cmp.3 = icmp sge i16 %l.3, 16383 981 %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383 982 store i16 %s.3, i16* %gep.3, align 2 983 984 %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4 985 %l.4 = load i16, i16* %gep.4 986 %cmp.4 = icmp sge i16 %l.4, 16383 987 %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383 988 store i16 %s.4, i16* %gep.4, align 2 989 990 %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5 991 %l.5 = load i16, i16* %gep.5 992 %cmp.5 = icmp sge i16 %l.5, 16383 993 %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383 994 store i16 %s.5, i16* %gep.5, align 2 995 996 %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6 997 %l.6 = load i16, i16* %gep.6 998 %cmp.6 = icmp sge i16 %l.6, 16383 999 %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383 1000 store i16 %s.6, i16* %gep.6, align 2 1001 1002 %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7 1003 %l.7 = load i16, i16* %gep.7 1004 %cmp.7 = icmp sge i16 %l.7, 16383 1005 %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383 1006 store i16 %s.7, i16* %gep.7, align 2 1007 ret void 1008} 1009 1010define void @select_smax_sge_4xi32(i32* %ptr, i32 %x) { 1011; CHECK-LABEL: @select_smax_sge_4xi32( 1012; CHECK-NEXT: entry: 1013; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>* 1014; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 1015; CHECK-NEXT: [[TMP2:%.*]] = icmp sge <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383> 1016; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383> 1017; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* 1018; CHECK-NEXT: store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4 1019; CHECK-NEXT: ret void 1020; 1021entry: 1022 %l.0 = load i32, i32* %ptr 1023 %cmp.0 = icmp sge i32 %l.0, 16383 1024 %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383 1025 store i32 %s.0, i32* %ptr, align 4 1026 1027 %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1 1028 %l.1 = load i32, i32* %gep.1 1029 %cmp.1 = icmp sge i32 %l.1, 16383 1030 %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383 1031 store i32 %s.1, i32* %gep.1, align 4 1032 1033 %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2 1034 %l.2 = load i32, i32* %gep.2 1035 %cmp.2 = icmp sge i32 %l.2, 16383 1036 %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383 1037 store i32 %s.2, i32* %gep.2, align 4 1038 1039 %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3 1040 %l.3 = load i32, i32* %gep.3 1041 %cmp.3 = icmp sge i32 %l.3, 16383 1042 %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383 1043 store i32 %s.3, i32* %gep.3, align 4 1044 1045 ret void 1046} 1047 1048; There is no <2 x i64> version of smax, but we can efficiently lower 1049; compare/select pairs with uniform predicates. 1050define void @select_smax_sge_2xi64(i64* %ptr, i64 %x) { 1051; CHECK-LABEL: @select_smax_sge_2xi64( 1052; CHECK-NEXT: entry: 1053; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>* 1054; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8 1055; CHECK-NEXT: [[TMP2:%.*]] = icmp sge <2 x i64> [[TMP1]], <i64 16383, i64 16383> 1056; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383> 1057; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>* 1058; CHECK-NEXT: store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4 1059; CHECK-NEXT: ret void 1060; 1061entry: 1062 %l.0 = load i64, i64* %ptr 1063 %cmp.0 = icmp sge i64 %l.0, 16383 1064 %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383 1065 store i64 %s.0, i64* %ptr, align 4 1066 1067 %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1 1068 %l.1 = load i64, i64* %gep.1 1069 %cmp.1 = icmp sge i64 %l.1, 16383 1070 %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383 1071 store i64 %s.1, i64* %gep.1, align 4 1072 1073 ret void 1074} 1075