1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 5 6define i32 @sadd_sat32(i32 %a, i32 %b) { 7; CHECK-LABEL: @sadd_sat32( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 10; CHECK-NEXT: ret i32 [[TMP0]] 11; 12entry: 13 %conv = sext i32 %a to i64 14 %conv1 = sext i32 %b to i64 15 %add = add i64 %conv1, %conv 16 %0 = icmp slt i64 %add, 2147483647 17 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 18 %1 = icmp sgt i64 %spec.store.select, -2147483648 19 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 20 %conv7 = trunc i64 %spec.store.select8 to i32 21 ret i32 %conv7 22} 23 24define i32 @sadd_sat32_mm(i32 %a, i32 %b) { 25; CHECK-LABEL: @sadd_sat32_mm( 26; CHECK-NEXT: entry: 27; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 28; CHECK-NEXT: ret i32 [[TMP0]] 29; 30entry: 31 %conv = sext i32 %a to i64 32 %conv1 = sext i32 %b to i64 33 %add = add i64 %conv1, %conv 34 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647) 35 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 36 %conv7 = trunc i64 %spec.store.select8 to i32 37 ret i32 %conv7 38} 39 40define i32 @ssub_sat32(i32 %a, i32 %b) { 41; CHECK-LABEL: @ssub_sat32( 42; CHECK-NEXT: entry: 43; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 44; CHECK-NEXT: ret i32 [[TMP0]] 45; 46entry: 47 %conv = sext i32 %a to i64 48 %conv1 = sext i32 %b to i64 49 %sub = sub i64 %conv, %conv1 50 %0 = icmp slt i64 %sub, 2147483647 51 %spec.store.select = select i1 %0, i64 %sub, i64 2147483647 52 %1 = icmp sgt i64 %spec.store.select, -2147483648 53 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 54 %conv7 = trunc i64 %spec.store.select8 to i32 55 ret i32 %conv7 56} 57 58define i32 @ssub_sat32_mm(i32 %a, i32 %b) { 59; CHECK-LABEL: @ssub_sat32_mm( 60; CHECK-NEXT: entry: 61; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 62; CHECK-NEXT: ret i32 [[TMP0]] 63; 64entry: 65 %conv = sext i32 %a to i64 66 %conv1 = sext i32 %b to i64 67 %sub = sub i64 %conv, %conv1 68 %spec.store.select = call i64 @llvm.smin.i64(i64 %sub, i64 2147483647) 69 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 70 %conv7 = trunc i64 %spec.store.select8 to i32 71 ret i32 %conv7 72} 73 74define i32 @smul_sat32(i32 %a, i32 %b) { 75; CHECK-LABEL: @smul_sat32( 76; CHECK-NEXT: entry: 77; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 78; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 79; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]] 80; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647) 81; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648) 82; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 83; CHECK-NEXT: ret i32 [[CONV7]] 84; 85entry: 86 %conv = sext i32 %a to i64 87 %conv1 = sext i32 %b to i64 88 %add = mul i64 %conv1, %conv 89 %0 = icmp slt i64 %add, 2147483647 90 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 91 %1 = icmp sgt i64 %spec.store.select, -2147483648 92 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 93 %conv7 = trunc i64 %spec.store.select8 to i32 94 ret i32 %conv7 95} 96 97define i32 @smul_sat32_mm(i32 %a, i32 %b) { 98; CHECK-LABEL: @smul_sat32_mm( 99; CHECK-NEXT: entry: 100; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 101; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 102; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]] 103; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647) 104; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648) 105; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 106; CHECK-NEXT: ret i32 [[CONV7]] 107; 108entry: 109 %conv = sext i32 %a to i64 110 %conv1 = sext i32 %b to i64 111 %add = mul i64 %conv1, %conv 112 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647) 113 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 114 %conv7 = trunc i64 %spec.store.select8 to i32 115 ret i32 %conv7 116} 117 118define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) { 119; CHECK-LABEL: @sadd_sat16( 120; CHECK-NEXT: entry: 121; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]]) 122; CHECK-NEXT: ret i16 [[TMP0]] 123; 124entry: 125 %conv = sext i16 %a to i32 126 %conv1 = sext i16 %b to i32 127 %add = add i32 %conv1, %conv 128 %0 = icmp slt i32 %add, 32767 129 %spec.store.select = select i1 %0, i32 %add, i32 32767 130 %1 = icmp sgt i32 %spec.store.select, -32768 131 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768 132 %conv9 = trunc i32 %spec.store.select10 to i16 133 ret i16 %conv9 134} 135 136define signext i16 @sadd_sat16_mm(i16 signext %a, i16 signext %b) { 137; CHECK-LABEL: @sadd_sat16_mm( 138; CHECK-NEXT: entry: 139; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]]) 140; CHECK-NEXT: ret i16 [[TMP0]] 141; 142entry: 143 %conv = sext i16 %a to i32 144 %conv1 = sext i16 %b to i32 145 %add = add i32 %conv1, %conv 146 %spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 32767) 147 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 148 %conv9 = trunc i32 %spec.store.select10 to i16 149 ret i16 %conv9 150} 151 152define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) { 153; CHECK-LABEL: @ssub_sat16( 154; CHECK-NEXT: entry: 155; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]]) 156; CHECK-NEXT: ret i16 [[TMP0]] 157; 158entry: 159 %conv = sext i16 %a to i32 160 %conv1 = sext i16 %b to i32 161 %sub = sub i32 %conv, %conv1 162 %0 = icmp slt i32 %sub, 32767 163 %spec.store.select = select i1 %0, i32 %sub, i32 32767 164 %1 = icmp sgt i32 %spec.store.select, -32768 165 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768 166 %conv9 = trunc i32 %spec.store.select10 to i16 167 ret i16 %conv9 168} 169 170define signext i16 @ssub_sat16_mm(i16 signext %a, i16 signext %b) { 171; CHECK-LABEL: @ssub_sat16_mm( 172; CHECK-NEXT: entry: 173; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]]) 174; CHECK-NEXT: ret i16 [[TMP0]] 175; 176entry: 177 %conv = sext i16 %a to i32 178 %conv1 = sext i16 %b to i32 179 %sub = sub i32 %conv, %conv1 180 %spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 32767) 181 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 182 %conv9 = trunc i32 %spec.store.select10 to i16 183 ret i16 %conv9 184} 185 186define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) { 187; CHECK-LABEL: @sadd_sat8( 188; CHECK-NEXT: entry: 189; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]]) 190; CHECK-NEXT: ret i8 [[TMP0]] 191; 192entry: 193 %conv = sext i8 %a to i32 194 %conv1 = sext i8 %b to i32 195 %add = add i32 %conv1, %conv 196 %0 = icmp slt i32 %add, 127 197 %spec.store.select = select i1 %0, i32 %add, i32 127 198 %1 = icmp sgt i32 %spec.store.select, -128 199 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128 200 %conv9 = trunc i32 %spec.store.select10 to i8 201 ret i8 %conv9 202} 203 204define signext i8 @sadd_sat8_mm(i8 signext %a, i8 signext %b) { 205; CHECK-LABEL: @sadd_sat8_mm( 206; CHECK-NEXT: entry: 207; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]]) 208; CHECK-NEXT: ret i8 [[TMP0]] 209; 210entry: 211 %conv = sext i8 %a to i32 212 %conv1 = sext i8 %b to i32 213 %add = add i32 %conv1, %conv 214 %spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 127) 215 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128) 216 %conv9 = trunc i32 %spec.store.select10 to i8 217 ret i8 %conv9 218} 219 220define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) { 221; CHECK-LABEL: @ssub_sat8( 222; CHECK-NEXT: entry: 223; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]]) 224; CHECK-NEXT: ret i8 [[TMP0]] 225; 226entry: 227 %conv = sext i8 %a to i32 228 %conv1 = sext i8 %b to i32 229 %sub = sub i32 %conv, %conv1 230 %0 = icmp slt i32 %sub, 127 231 %spec.store.select = select i1 %0, i32 %sub, i32 127 232 %1 = icmp sgt i32 %spec.store.select, -128 233 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128 234 %conv9 = trunc i32 %spec.store.select10 to i8 235 ret i8 %conv9 236} 237 238define signext i8 @ssub_sat8_mm(i8 signext %a, i8 signext %b) { 239; CHECK-LABEL: @ssub_sat8_mm( 240; CHECK-NEXT: entry: 241; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]]) 242; CHECK-NEXT: ret i8 [[TMP0]] 243; 244entry: 245 %conv = sext i8 %a to i32 246 %conv1 = sext i8 %b to i32 247 %sub = sub i32 %conv, %conv1 248 %spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 127) 249 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128) 250 %conv9 = trunc i32 %spec.store.select10 to i8 251 ret i8 %conv9 252} 253 254define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) { 255; CHECK-LABEL: @sadd_sat64( 256; CHECK-NEXT: entry: 257; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.sadd.sat.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 258; CHECK-NEXT: ret i64 [[TMP0]] 259; 260entry: 261 %conv = sext i64 %a to i65 262 %conv1 = sext i64 %b to i65 263 %add = add i65 %conv1, %conv 264 %0 = icmp slt i65 %add, 9223372036854775807 265 %spec.store.select = select i1 %0, i65 %add, i65 9223372036854775807 266 %1 = icmp sgt i65 %spec.store.select, -9223372036854775808 267 %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808 268 %conv9 = trunc i65 %spec.store.select10 to i64 269 ret i64 %conv9 270} 271 272define signext i64 @ssub_sat64(i64 signext %a, i64 signext %b) { 273; CHECK-LABEL: @ssub_sat64( 274; CHECK-NEXT: entry: 275; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.ssub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) 276; CHECK-NEXT: ret i64 [[TMP0]] 277; 278entry: 279 %conv = sext i64 %a to i65 280 %conv1 = sext i64 %b to i65 281 %sub = sub i65 %conv, %conv1 282 %0 = icmp slt i65 %sub, 9223372036854775807 283 %spec.store.select = select i1 %0, i65 %sub, i65 9223372036854775807 284 %1 = icmp sgt i65 %spec.store.select, -9223372036854775808 285 %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808 286 %conv9 = trunc i65 %spec.store.select10 to i64 287 ret i64 %conv9 288} 289 290define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) { 291; CHECK-LABEL: @sadd_sat4( 292; CHECK-NEXT: entry: 293; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32 294; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32 295; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]] 296; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 7) 297; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -8) 298; CHECK-NEXT: [[CONV9:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT10]] to i4 299; CHECK-NEXT: ret i4 [[CONV9]] 300; 301entry: 302 %conv = sext i4 %a to i32 303 %conv1 = sext i4 %b to i32 304 %add = add i32 %conv1, %conv 305 %0 = icmp slt i32 %add, 7 306 %spec.store.select = select i1 %0, i32 %add, i32 7 307 %1 = icmp sgt i32 %spec.store.select, -8 308 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8 309 %conv9 = trunc i32 %spec.store.select10 to i4 310 ret i4 %conv9 311} 312 313define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) { 314; CHECK-LABEL: @ssub_sat4( 315; CHECK-NEXT: entry: 316; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32 317; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32 318; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]] 319; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[SUB]], i32 7) 320; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -8) 321; CHECK-NEXT: [[CONV9:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT10]] to i4 322; CHECK-NEXT: ret i4 [[CONV9]] 323; 324entry: 325 %conv = sext i4 %a to i32 326 %conv1 = sext i4 %b to i32 327 %sub = sub i32 %conv, %conv1 328 %0 = icmp slt i32 %sub, 7 329 %spec.store.select = select i1 %0, i32 %sub, i32 7 330 %1 = icmp sgt i32 %spec.store.select, -8 331 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8 332 %conv9 = trunc i32 %spec.store.select10 to i4 333 ret i4 %conv9 334} 335 336define <4 x i32> @sadd_satv4i32(<4 x i32> %a, <4 x i32> %b) { 337; CHECK-LABEL: @sadd_satv4i32( 338; CHECK-NEXT: entry: 339; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]]) 340; CHECK-NEXT: ret <4 x i32> [[TMP0]] 341; 342entry: 343 %conv = sext <4 x i32> %a to <4 x i64> 344 %conv1 = sext <4 x i32> %b to <4 x i64> 345 %add = add <4 x i64> %conv1, %conv 346 %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 347 %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 348 %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648> 349 %spec.store.select8 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648> 350 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32> 351 ret <4 x i32> %conv7 352} 353 354define <4 x i32> @sadd_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) { 355; CHECK-LABEL: @sadd_satv4i32_mm( 356; CHECK-NEXT: entry: 357; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]]) 358; CHECK-NEXT: ret <4 x i32> [[TMP0]] 359; 360entry: 361 %conv = sext <4 x i32> %a to <4 x i64> 362 %conv1 = sext <4 x i32> %b to <4 x i64> 363 %add = add <4 x i64> %conv1, %conv 364 %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>) 365 %spec.store.select8 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>) 366 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32> 367 ret <4 x i32> %conv7 368} 369 370define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) { 371; CHECK-LABEL: @ssub_satv4i32( 372; CHECK-NEXT: entry: 373; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]]) 374; CHECK-NEXT: ret <4 x i32> [[TMP0]] 375; 376entry: 377 %conv = sext <4 x i32> %a to <4 x i64> 378 %conv1 = sext <4 x i32> %b to <4 x i64> 379 %add = sub <4 x i64> %conv1, %conv 380 %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 381 %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 382 %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648> 383 %spec.store.select8 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648> 384 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32> 385 ret <4 x i32> %conv7 386} 387 388define <4 x i32> @ssub_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) { 389; CHECK-LABEL: @ssub_satv4i32_mm( 390; CHECK-NEXT: entry: 391; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]]) 392; CHECK-NEXT: ret <4 x i32> [[TMP0]] 393; 394entry: 395 %conv = sext <4 x i32> %a to <4 x i64> 396 %conv1 = sext <4 x i32> %b to <4 x i64> 397 %add = sub <4 x i64> %conv1, %conv 398 %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>) 399 %spec.store.select8 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>) 400 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32> 401 ret <4 x i32> %conv7 402} 403 404define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) { 405; CHECK-LABEL: @sadd_satv4i4( 406; CHECK-NEXT: entry: 407; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]] 408; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[ADD]], <4 x i32> splat (i32 15)) 409; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> splat (i32 -16)) 410; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]] 411; 412entry: 413 %add = add <4 x i32> %a, %b 414 %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15> 415 %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15> 416 %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16> 417 %spec.store.select8 = select <4 x i1> %1, <4 x i32> %spec.store.select, <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16> 418 ret <4 x i32> %spec.store.select8 419} 420 421define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) { 422; CHECK-LABEL: @ssub_satv4i4( 423; CHECK-NEXT: entry: 424; CHECK-NEXT: [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]] 425; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[ADD]], <4 x i32> splat (i32 15)) 426; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> splat (i32 -16)) 427; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]] 428; 429entry: 430 %add = sub <4 x i32> %a, %b 431 %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15> 432 %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15> 433 %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16> 434 %spec.store.select8 = select <4 x i1> %1, <4 x i32> %spec.store.select, <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16> 435 ret <4 x i32> %spec.store.select8 436} 437 438 439define i32 @sadd_sat32_extrause_1(i32 %a, i32 %b) { 440; CHECK-LABEL: @sadd_sat32_extrause_1( 441; CHECK-NEXT: entry: 442; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 443; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64 444; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT8]]) 445; CHECK-NEXT: ret i32 [[TMP0]] 446; 447entry: 448 %conv = sext i32 %a to i64 449 %conv1 = sext i32 %b to i64 450 %add = add i64 %conv1, %conv 451 %0 = icmp slt i64 %add, 2147483647 452 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 453 %1 = icmp sgt i64 %spec.store.select, -2147483648 454 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 455 %conv7 = trunc i64 %spec.store.select8 to i32 456 call void @use64(i64 %spec.store.select8) 457 ret i32 %conv7 458} 459 460define i32 @sadd_sat32_extrause_2(i32 %a, i32 %b) { 461; CHECK-LABEL: @sadd_sat32_extrause_2( 462; CHECK-NEXT: entry: 463; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 464; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 465; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 466; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647) 467; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648) 468; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 469; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT]]) 470; CHECK-NEXT: ret i32 [[CONV7]] 471; 472entry: 473 %conv = sext i32 %a to i64 474 %conv1 = sext i32 %b to i64 475 %add = add i64 %conv1, %conv 476 %0 = icmp slt i64 %add, 2147483647 477 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 478 %1 = icmp sgt i64 %spec.store.select, -2147483648 479 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 480 %conv7 = trunc i64 %spec.store.select8 to i32 481 call void @use64(i64 %spec.store.select) 482 ret i32 %conv7 483} 484 485define i32 @sadd_sat32_extrause_2_mm(i32 %a, i32 %b) { 486; CHECK-LABEL: @sadd_sat32_extrause_2_mm( 487; CHECK-NEXT: entry: 488; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 489; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 490; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 491; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647) 492; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648) 493; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 494; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT]]) 495; CHECK-NEXT: ret i32 [[CONV7]] 496; 497entry: 498 %conv = sext i32 %a to i64 499 %conv1 = sext i32 %b to i64 500 %add = add i64 %conv1, %conv 501 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647) 502 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 503 %conv7 = trunc i64 %spec.store.select8 to i32 504 call void @use64(i64 %spec.store.select) 505 ret i32 %conv7 506} 507 508define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) { 509; CHECK-LABEL: @sadd_sat32_extrause_3( 510; CHECK-NEXT: entry: 511; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 512; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 513; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 514; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647) 515; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648) 516; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 517; CHECK-NEXT: call void @use64(i64 [[ADD]]) 518; CHECK-NEXT: ret i32 [[CONV7]] 519; 520entry: 521 %conv = sext i32 %a to i64 522 %conv1 = sext i32 %b to i64 523 %add = add i64 %conv1, %conv 524 %0 = icmp slt i64 %add, 2147483647 525 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 526 %1 = icmp sgt i64 %spec.store.select, -2147483648 527 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 528 %conv7 = trunc i64 %spec.store.select8 to i32 529 call void @use64(i64 %add) 530 ret i32 %conv7 531} 532 533define i32 @sadd_sat32_extrause_3_mm(i32 %a, i32 %b) { 534; CHECK-LABEL: @sadd_sat32_extrause_3_mm( 535; CHECK-NEXT: entry: 536; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 537; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 538; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 539; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647) 540; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648) 541; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 542; CHECK-NEXT: call void @use64(i64 [[ADD]]) 543; CHECK-NEXT: ret i32 [[CONV7]] 544; 545entry: 546 %conv = sext i32 %a to i64 547 %conv1 = sext i32 %b to i64 548 %add = add i64 %conv1, %conv 549 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647) 550 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 551 %conv7 = trunc i64 %spec.store.select8 to i32 552 call void @use64(i64 %add) 553 ret i32 %conv7 554} 555 556define i32 @sadd_sat32_trunc(i32 %a, i32 %b) { 557; CHECK-LABEL: @sadd_sat32_trunc( 558; CHECK-NEXT: entry: 559; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 560; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 561; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 562; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 32767) 563; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -32768) 564; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 565; CHECK-NEXT: ret i32 [[CONV7]] 566; 567entry: 568 %conv = sext i32 %a to i64 569 %conv1 = sext i32 %b to i64 570 %add = add i64 %conv1, %conv 571 %0 = icmp slt i64 %add, 32767 572 %spec.store.select = select i1 %0, i64 %add, i64 32767 573 %1 = icmp sgt i64 %spec.store.select, -32768 574 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -32768 575 %conv7 = trunc i64 %spec.store.select8 to i32 576 ret i32 %conv7 577} 578 579define i32 @sadd_sat32_ext16(i32 %a, i16 %b) { 580; CHECK-LABEL: @sadd_sat32_ext16( 581; CHECK-NEXT: entry: 582; CHECK-NEXT: [[TMP0:%.*]] = sext i16 [[B:%.*]] to i32 583; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[A:%.*]]) 584; CHECK-NEXT: ret i32 [[TMP1]] 585; 586entry: 587 %conv = sext i32 %a to i64 588 %conv1 = sext i16 %b to i64 589 %add = add i64 %conv1, %conv 590 %0 = icmp slt i64 %add, 2147483647 591 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 592 %1 = icmp sgt i64 %spec.store.select, -2147483648 593 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 594 %conv7 = trunc i64 %spec.store.select8 to i32 595 ret i32 %conv7 596} 597 598define i8 @sadd_sat8_ext8(i8 %a, i16 %b) { 599; CHECK-LABEL: @sadd_sat8_ext8( 600; CHECK-NEXT: entry: 601; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 602; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32 603; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]] 604; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 127) 605; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -128) 606; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT8]] to i8 607; CHECK-NEXT: ret i8 [[CONV7]] 608; 609entry: 610 %conv = sext i8 %a to i32 611 %conv1 = sext i16 %b to i32 612 %add = add i32 %conv1, %conv 613 %0 = icmp slt i32 %add, 127 614 %spec.store.select = select i1 %0, i32 %add, i32 127 615 %1 = icmp sgt i32 %spec.store.select, -128 616 %spec.store.select8 = select i1 %1, i32 %spec.store.select, i32 -128 617 %conv7 = trunc i32 %spec.store.select8 to i8 618 ret i8 %conv7 619} 620 621define i32 @sadd_sat32_zext(i32 %a, i32 %b) { 622; CHECK-LABEL: @sadd_sat32_zext( 623; CHECK-NEXT: entry: 624; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[A:%.*]] to i64 625; CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[B:%.*]] to i64 626; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[CONV1]], [[CONV]] 627; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.umin.i64(i64 [[ADD]], i64 2147483647) 628; CHECK-NEXT: [[CONV7:%.*]] = trunc nuw nsw i64 [[SPEC_STORE_SELECT]] to i32 629; CHECK-NEXT: ret i32 [[CONV7]] 630; 631entry: 632 %conv = zext i32 %a to i64 633 %conv1 = zext i32 %b to i64 634 %add = add i64 %conv1, %conv 635 %0 = icmp slt i64 %add, 2147483647 636 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 637 %1 = icmp sgt i64 %spec.store.select, -2147483648 638 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 639 %conv7 = trunc i64 %spec.store.select8 to i32 640 ret i32 %conv7 641} 642 643define i32 @sadd_sat32_maxmin(i32 %a, i32 %b) { 644; CHECK-LABEL: @sadd_sat32_maxmin( 645; CHECK-NEXT: entry: 646; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 647; CHECK-NEXT: ret i32 [[TMP0]] 648; 649entry: 650 %conv = sext i32 %a to i64 651 %conv1 = sext i32 %b to i64 652 %add = add i64 %conv1, %conv 653 %0 = icmp sgt i64 %add, -2147483648 654 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 655 %1 = icmp slt i64 %spec.store.select, 2147483647 656 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 657 %conv7 = trunc i64 %spec.store.select8 to i32 658 ret i32 %conv7 659} 660 661define i64 @sadd_sat32_notrunc(i32 %a, i32 %b) { 662; CHECK-LABEL: @sadd_sat32_notrunc( 663; CHECK-NEXT: entry: 664; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 665; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64 666; CHECK-NEXT: ret i64 [[SPEC_STORE_SELECT8]] 667; 668entry: 669 %conv = sext i32 %a to i64 670 %conv1 = sext i32 %b to i64 671 %add = add i64 %conv1, %conv 672 %0 = icmp sgt i64 %add, -2147483648 673 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 674 %1 = icmp slt i64 %spec.store.select, 2147483647 675 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 676 ret i64 %spec.store.select8 677} 678 679define i32 @ashrA(i64 %a, i32 %b) { 680; CHECK-LABEL: @ashrA( 681; CHECK-NEXT: entry: 682; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[A:%.*]], 32 683; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw i64 [[TMP0]] to i32 684; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP1]], i32 [[B:%.*]]) 685; CHECK-NEXT: ret i32 [[TMP2]] 686; 687entry: 688 %conv = ashr i64 %a, 32 689 %conv1 = sext i32 %b to i64 690 %add = add i64 %conv1, %conv 691 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647) 692 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 693 %conv7 = trunc i64 %spec.store.select8 to i32 694 ret i32 %conv7 695} 696 697define i32 @ashrB(i32 %a, i64 %b) { 698; CHECK-LABEL: @ashrB( 699; CHECK-NEXT: entry: 700; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[B:%.*]], 32 701; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw i64 [[TMP0]] to i32 702; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP1]], i32 [[A:%.*]]) 703; CHECK-NEXT: ret i32 [[TMP2]] 704; 705entry: 706 %conv = sext i32 %a to i64 707 %conv1 = ashr i64 %b, 32 708 %add = add i64 %conv1, %conv 709 %0 = icmp sgt i64 %add, -2147483648 710 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 711 %1 = icmp slt i64 %spec.store.select, 2147483647 712 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 713 %conv7 = trunc i64 %spec.store.select8 to i32 714 ret i32 %conv7 715} 716 717define i32 @ashrAB(i64 %a, i64 %b) { 718; CHECK-LABEL: @ashrAB( 719; CHECK-NEXT: entry: 720; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[A:%.*]], 32 721; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[B:%.*]], 32 722; CHECK-NEXT: [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32 723; CHECK-NEXT: [[TMP3:%.*]] = trunc nuw i64 [[TMP0]] to i32 724; CHECK-NEXT: [[TMP4:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP2]], i32 [[TMP3]]) 725; CHECK-NEXT: ret i32 [[TMP4]] 726; 727entry: 728 %conv = ashr i64 %a, 32 729 %conv1 = ashr i64 %b, 32 730 %add = add i64 %conv1, %conv 731 %0 = icmp sgt i64 %add, -2147483648 732 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 733 %1 = icmp slt i64 %spec.store.select, 2147483647 734 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 735 %conv7 = trunc i64 %spec.store.select8 to i32 736 ret i32 %conv7 737} 738 739define i32 @ashrA31(i64 %a, i32 %b) { 740; CHECK-LABEL: @ashrA31( 741; CHECK-NEXT: entry: 742; CHECK-NEXT: [[CONV:%.*]] = ashr i64 [[A:%.*]], 31 743; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 744; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV]], [[CONV1]] 745; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -2147483648) 746; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[SPEC_STORE_SELECT]], i64 2147483647) 747; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32 748; CHECK-NEXT: ret i32 [[CONV7]] 749; 750entry: 751 %conv = ashr i64 %a, 31 752 %conv1 = sext i32 %b to i64 753 %add = add i64 %conv1, %conv 754 %0 = icmp sgt i64 %add, -2147483648 755 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 756 %1 = icmp slt i64 %spec.store.select, 2147483647 757 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 758 %conv7 = trunc i64 %spec.store.select8 to i32 759 ret i32 %conv7 760} 761 762define i32 @ashrA33(i64 %a, i32 %b) { 763; CHECK-LABEL: @ashrA33( 764; CHECK-NEXT: entry: 765; CHECK-NEXT: [[CONV:%.*]] = ashr i64 [[A:%.*]], 33 766; CHECK-NEXT: [[TMP0:%.*]] = trunc nsw i64 [[CONV]] to i32 767; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[B:%.*]]) 768; CHECK-NEXT: ret i32 [[TMP1]] 769; 770entry: 771 %conv = ashr i64 %a, 33 772 %conv1 = sext i32 %b to i64 773 %add = add i64 %conv1, %conv 774 %0 = icmp sgt i64 %add, -2147483648 775 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 776 %1 = icmp slt i64 %spec.store.select, 2147483647 777 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 778 %conv7 = trunc i64 %spec.store.select8 to i32 779 ret i32 %conv7 780} 781 782define <2 x i8> @ashrv2i8(<2 x i16> %a, <2 x i8> %b) { 783; CHECK-LABEL: @ashrv2i8( 784; CHECK-NEXT: entry: 785; CHECK-NEXT: [[CONV:%.*]] = ashr <2 x i16> [[A:%.*]], <i16 8, i16 12> 786; CHECK-NEXT: [[CONV1:%.*]] = sext <2 x i8> [[B:%.*]] to <2 x i16> 787; CHECK-NEXT: [[ADD:%.*]] = add <2 x i16> [[CONV]], [[CONV1]] 788; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[ADD]], <2 x i16> splat (i16 -128)) 789; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[SPEC_STORE_SELECT]], <2 x i16> splat (i16 127)) 790; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw <2 x i16> [[SPEC_STORE_SELECT8]] to <2 x i8> 791; CHECK-NEXT: ret <2 x i8> [[CONV7]] 792; 793entry: 794 %conv = ashr <2 x i16> %a, <i16 8, i16 12> 795 %conv1 = sext <2 x i8> %b to <2 x i16> 796 %add = add <2 x i16> %conv1, %conv 797 %0 = icmp sgt <2 x i16> %add, <i16 -128, i16 -128> 798 %spec.store.select = select <2 x i1> %0, <2 x i16> %add, <2 x i16> <i16 -128, i16 -128> 799 %1 = icmp slt <2 x i16> %spec.store.select, <i16 127, i16 127> 800 %spec.store.select8 = select <2 x i1> %1, <2 x i16> %spec.store.select, <2 x i16> <i16 127, i16 127> 801 %conv7 = trunc <2 x i16> %spec.store.select8 to <2 x i8> 802 ret <2 x i8> %conv7 803} 804 805define <2 x i8> @ashrv2i8_s(<2 x i16> %a, <2 x i8> %b) { 806; CHECK-LABEL: @ashrv2i8_s( 807; CHECK-NEXT: entry: 808; CHECK-NEXT: [[TMP0:%.*]] = lshr <2 x i16> [[A:%.*]], splat (i16 8) 809; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw <2 x i16> [[TMP0]] to <2 x i8> 810; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[TMP1]], <2 x i8> [[B:%.*]]) 811; CHECK-NEXT: ret <2 x i8> [[TMP2]] 812; 813entry: 814 %conv = ashr <2 x i16> %a, <i16 8, i16 8> 815 %conv1 = sext <2 x i8> %b to <2 x i16> 816 %add = add <2 x i16> %conv1, %conv 817 %0 = icmp sgt <2 x i16> %add, <i16 -128, i16 -128> 818 %spec.store.select = select <2 x i1> %0, <2 x i16> %add, <2 x i16> <i16 -128, i16 -128> 819 %1 = icmp slt <2 x i16> %spec.store.select, <i16 127, i16 127> 820 %spec.store.select8 = select <2 x i1> %1, <2 x i16> %spec.store.select, <2 x i16> <i16 127, i16 127> 821 %conv7 = trunc <2 x i16> %spec.store.select8 to <2 x i8> 822 ret <2 x i8> %conv7 823} 824 825define i16 @or(i8 %X, i16 %Y) { 826; CHECK-LABEL: @or( 827; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i8 828; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], -16 829; CHECK-NEXT: [[TMP3:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[TMP2]]) 830; CHECK-NEXT: [[L12:%.*]] = sext i8 [[TMP3]] to i16 831; CHECK-NEXT: ret i16 [[L12]] 832; 833 %conv10 = sext i8 %X to i16 834 %conv14 = or i16 %Y, 65520 835 %sub = sub nsw i16 %conv10, %conv14 836 %l9 = icmp sgt i16 %sub, -128 837 %l10 = select i1 %l9, i16 %sub, i16 -128 838 %l11 = icmp slt i16 %l10, 127 839 %l12 = select i1 %l11, i16 %l10, i16 127 840 ret i16 %l12 841} 842 843define i16 @const(i8 %X) { 844; CHECK-LABEL: @const( 845; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 117) 846; CHECK-NEXT: [[NARROW:%.*]] = add nsw i8 [[TMP1]], 10 847; CHECK-NEXT: [[L12:%.*]] = sext i8 [[NARROW]] to i16 848; CHECK-NEXT: ret i16 [[L12]] 849; 850 %conv10 = sext i8 %X to i16 851 %sub = add i16 %conv10, 10 852 %l9 = icmp sgt i16 %sub, -128 853 %l10 = select i1 %l9, i16 %sub, i16 -128 854 %l11 = icmp slt i16 %l10, 127 855 %l12 = select i1 %l11, i16 %l10, i16 127 856 ret i16 %l12 857} 858 859declare void @use64(i64) 860declare i64 @llvm.smin.i64(i64, i64) 861declare i64 @llvm.smax.i64(i64, i64) 862declare i32 @llvm.smin.i32(i32, i32) 863declare i32 @llvm.smax.i32(i32, i32) 864declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>) 865declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>) 866