1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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 @ssub_sat32(i32 %a, i32 %b) { 25; CHECK-LABEL: @ssub_sat32( 26; CHECK-NEXT: entry: 27; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 28; CHECK-NEXT: ret i32 [[TMP0]] 29; 30entry: 31 %conv = sext i32 %a to i64 32 %conv1 = sext i32 %b to i64 33 %sub = sub i64 %conv, %conv1 34 %0 = icmp slt i64 %sub, 2147483647 35 %spec.store.select = select i1 %0, i64 %sub, i64 2147483647 36 %1 = icmp sgt i64 %spec.store.select, -2147483648 37 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 38 %conv7 = trunc i64 %spec.store.select8 to i32 39 ret i32 %conv7 40} 41 42define i32 @smul_sat32(i32 %a, i32 %b) { 43; CHECK-LABEL: @smul_sat32( 44; CHECK-NEXT: entry: 45; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 46; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 47; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]] 48; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647 49; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647 50; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648 51; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648 52; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32 53; CHECK-NEXT: ret i32 [[CONV7]] 54; 55entry: 56 %conv = sext i32 %a to i64 57 %conv1 = sext i32 %b to i64 58 %add = mul i64 %conv1, %conv 59 %0 = icmp slt i64 %add, 2147483647 60 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 61 %1 = icmp sgt i64 %spec.store.select, -2147483648 62 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 63 %conv7 = trunc i64 %spec.store.select8 to i32 64 ret i32 %conv7 65} 66 67define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) { 68; CHECK-LABEL: @sadd_sat16( 69; CHECK-NEXT: entry: 70; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]]) 71; CHECK-NEXT: ret i16 [[TMP0]] 72; 73entry: 74 %conv = sext i16 %a to i32 75 %conv1 = sext i16 %b to i32 76 %add = add i32 %conv1, %conv 77 %0 = icmp slt i32 %add, 32767 78 %spec.store.select = select i1 %0, i32 %add, i32 32767 79 %1 = icmp sgt i32 %spec.store.select, -32768 80 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768 81 %conv9 = trunc i32 %spec.store.select10 to i16 82 ret i16 %conv9 83} 84 85define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) { 86; CHECK-LABEL: @ssub_sat16( 87; CHECK-NEXT: entry: 88; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]]) 89; CHECK-NEXT: ret i16 [[TMP0]] 90; 91entry: 92 %conv = sext i16 %a to i32 93 %conv1 = sext i16 %b to i32 94 %sub = sub i32 %conv, %conv1 95 %0 = icmp slt i32 %sub, 32767 96 %spec.store.select = select i1 %0, i32 %sub, i32 32767 97 %1 = icmp sgt i32 %spec.store.select, -32768 98 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768 99 %conv9 = trunc i32 %spec.store.select10 to i16 100 ret i16 %conv9 101} 102 103define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) { 104; CHECK-LABEL: @sadd_sat8( 105; CHECK-NEXT: entry: 106; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]]) 107; CHECK-NEXT: ret i8 [[TMP0]] 108; 109entry: 110 %conv = sext i8 %a to i32 111 %conv1 = sext i8 %b to i32 112 %add = add i32 %conv1, %conv 113 %0 = icmp slt i32 %add, 127 114 %spec.store.select = select i1 %0, i32 %add, i32 127 115 %1 = icmp sgt i32 %spec.store.select, -128 116 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128 117 %conv9 = trunc i32 %spec.store.select10 to i8 118 ret i8 %conv9 119} 120 121define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) { 122; CHECK-LABEL: @ssub_sat8( 123; CHECK-NEXT: entry: 124; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]]) 125; CHECK-NEXT: ret i8 [[TMP0]] 126; 127entry: 128 %conv = sext i8 %a to i32 129 %conv1 = sext i8 %b to i32 130 %sub = sub i32 %conv, %conv1 131 %0 = icmp slt i32 %sub, 127 132 %spec.store.select = select i1 %0, i32 %sub, i32 127 133 %1 = icmp sgt i32 %spec.store.select, -128 134 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128 135 %conv9 = trunc i32 %spec.store.select10 to i8 136 ret i8 %conv9 137} 138 139define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) { 140; CHECK-LABEL: @sadd_sat64( 141; CHECK-NEXT: entry: 142; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.sadd.sat.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 143; CHECK-NEXT: ret i64 [[TMP0]] 144; 145entry: 146 %conv = sext i64 %a to i65 147 %conv1 = sext i64 %b to i65 148 %add = add i65 %conv1, %conv 149 %0 = icmp slt i65 %add, 9223372036854775807 150 %spec.store.select = select i1 %0, i65 %add, i65 9223372036854775807 151 %1 = icmp sgt i65 %spec.store.select, -9223372036854775808 152 %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808 153 %conv9 = trunc i65 %spec.store.select10 to i64 154 ret i64 %conv9 155} 156 157define signext i64 @ssub_sat64(i64 signext %a, i64 signext %b) { 158; CHECK-LABEL: @ssub_sat64( 159; CHECK-NEXT: entry: 160; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.ssub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) 161; CHECK-NEXT: ret i64 [[TMP0]] 162; 163entry: 164 %conv = sext i64 %a to i65 165 %conv1 = sext i64 %b to i65 166 %sub = sub i65 %conv, %conv1 167 %0 = icmp slt i65 %sub, 9223372036854775807 168 %spec.store.select = select i1 %0, i65 %sub, i65 9223372036854775807 169 %1 = icmp sgt i65 %spec.store.select, -9223372036854775808 170 %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808 171 %conv9 = trunc i65 %spec.store.select10 to i64 172 ret i64 %conv9 173} 174 175define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) { 176; CHECK-LABEL: @sadd_sat4( 177; CHECK-NEXT: entry: 178; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32 179; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32 180; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]] 181; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ADD]], 7 182; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 7 183; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8 184; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8 185; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4 186; CHECK-NEXT: ret i4 [[CONV9]] 187; 188entry: 189 %conv = sext i4 %a to i32 190 %conv1 = sext i4 %b to i32 191 %add = add i32 %conv1, %conv 192 %0 = icmp slt i32 %add, 7 193 %spec.store.select = select i1 %0, i32 %add, i32 7 194 %1 = icmp sgt i32 %spec.store.select, -8 195 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8 196 %conv9 = trunc i32 %spec.store.select10 to i4 197 ret i4 %conv9 198} 199 200define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) { 201; CHECK-LABEL: @ssub_sat4( 202; CHECK-NEXT: entry: 203; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32 204; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32 205; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]] 206; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[SUB]], 7 207; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SUB]], i32 7 208; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8 209; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8 210; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4 211; CHECK-NEXT: ret i4 [[CONV9]] 212; 213entry: 214 %conv = sext i4 %a to i32 215 %conv1 = sext i4 %b to i32 216 %sub = sub i32 %conv, %conv1 217 %0 = icmp slt i32 %sub, 7 218 %spec.store.select = select i1 %0, i32 %sub, i32 7 219 %1 = icmp sgt i32 %spec.store.select, -8 220 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8 221 %conv9 = trunc i32 %spec.store.select10 to i4 222 ret i4 %conv9 223} 224 225define <4 x i32> @sadd_satv4i32(<4 x i32> %a, <4 x i32> %b) { 226; CHECK-LABEL: @sadd_satv4i32( 227; CHECK-NEXT: entry: 228; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]]) 229; CHECK-NEXT: ret <4 x i32> [[TMP0]] 230; 231entry: 232 %conv = sext <4 x i32> %a to <4 x i64> 233 %conv1 = sext <4 x i32> %b to <4 x i64> 234 %add = add <4 x i64> %conv1, %conv 235 %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 236 %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 237 %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648> 238 %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> 239 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32> 240 ret <4 x i32> %conv7 241} 242 243define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) { 244; CHECK-LABEL: @ssub_satv4i32( 245; CHECK-NEXT: entry: 246; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]]) 247; CHECK-NEXT: ret <4 x i32> [[TMP0]] 248; 249entry: 250 %conv = sext <4 x i32> %a to <4 x i64> 251 %conv1 = sext <4 x i32> %b to <4 x i64> 252 %add = sub <4 x i64> %conv1, %conv 253 %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 254 %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647> 255 %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648> 256 %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> 257 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32> 258 ret <4 x i32> %conv7 259} 260 261define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) { 262; CHECK-LABEL: @sadd_satv4i4( 263; CHECK-NEXT: entry: 264; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]] 265; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15> 266; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[ADD]], <4 x i32> <i32 15, i32 15, i32 15, i32 15> 267; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16> 268; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16> 269; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]] 270; 271entry: 272 %add = add <4 x i32> %a, %b 273 %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15> 274 %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15> 275 %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16> 276 %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> 277 ret <4 x i32> %spec.store.select8 278} 279 280define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) { 281; CHECK-LABEL: @ssub_satv4i4( 282; CHECK-NEXT: entry: 283; CHECK-NEXT: [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]] 284; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15> 285; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[ADD]], <4 x i32> <i32 15, i32 15, i32 15, i32 15> 286; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16> 287; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16> 288; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]] 289; 290entry: 291 %add = sub <4 x i32> %a, %b 292 %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15> 293 %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15> 294 %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16> 295 %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> 296 ret <4 x i32> %spec.store.select8 297} 298 299 300define i32 @sadd_sat32_extrause_1(i32 %a, i32 %b) { 301; CHECK-LABEL: @sadd_sat32_extrause_1( 302; CHECK-NEXT: entry: 303; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 304; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64 305; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT8]]) 306; CHECK-NEXT: ret i32 [[TMP0]] 307; 308entry: 309 %conv = sext i32 %a to i64 310 %conv1 = sext i32 %b to i64 311 %add = add i64 %conv1, %conv 312 %0 = icmp slt i64 %add, 2147483647 313 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 314 %1 = icmp sgt i64 %spec.store.select, -2147483648 315 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 316 %conv7 = trunc i64 %spec.store.select8 to i32 317 call void @use64(i64 %spec.store.select8) 318 ret i32 %conv7 319} 320 321define i32 @sadd_sat32_extrause_2(i32 %a, i32 %b) { 322; CHECK-LABEL: @sadd_sat32_extrause_2( 323; CHECK-NEXT: entry: 324; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 325; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 326; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 327; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647 328; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647 329; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648 330; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648 331; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32 332; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT]]) 333; CHECK-NEXT: ret i32 [[CONV7]] 334; 335entry: 336 %conv = sext i32 %a to i64 337 %conv1 = sext i32 %b to i64 338 %add = add i64 %conv1, %conv 339 %0 = icmp slt i64 %add, 2147483647 340 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 341 %1 = icmp sgt i64 %spec.store.select, -2147483648 342 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 343 %conv7 = trunc i64 %spec.store.select8 to i32 344 call void @use64(i64 %spec.store.select) 345 ret i32 %conv7 346} 347 348define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) { 349; CHECK-LABEL: @sadd_sat32_extrause_3( 350; CHECK-NEXT: entry: 351; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 352; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 353; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 354; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647 355; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647 356; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648 357; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648 358; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32 359; CHECK-NEXT: call void @use64(i64 [[ADD]]) 360; CHECK-NEXT: ret i32 [[CONV7]] 361; 362entry: 363 %conv = sext i32 %a to i64 364 %conv1 = sext i32 %b to i64 365 %add = add i64 %conv1, %conv 366 %0 = icmp slt i64 %add, 2147483647 367 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 368 %1 = icmp sgt i64 %spec.store.select, -2147483648 369 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 370 %conv7 = trunc i64 %spec.store.select8 to i32 371 call void @use64(i64 %add) 372 ret i32 %conv7 373} 374 375define i32 @sadd_sat32_trunc(i32 %a, i32 %b) { 376; CHECK-LABEL: @sadd_sat32_trunc( 377; CHECK-NEXT: entry: 378; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 379; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64 380; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]] 381; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 32767 382; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 32767 383; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -32768 384; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -32768 385; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32 386; CHECK-NEXT: ret i32 [[CONV7]] 387; 388entry: 389 %conv = sext i32 %a to i64 390 %conv1 = sext i32 %b to i64 391 %add = add i64 %conv1, %conv 392 %0 = icmp slt i64 %add, 32767 393 %spec.store.select = select i1 %0, i64 %add, i64 32767 394 %1 = icmp sgt i64 %spec.store.select, -32768 395 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -32768 396 %conv7 = trunc i64 %spec.store.select8 to i32 397 ret i32 %conv7 398} 399 400define i32 @sadd_sat32_ext16(i32 %a, i16 %b) { 401; CHECK-LABEL: @sadd_sat32_ext16( 402; CHECK-NEXT: entry: 403; CHECK-NEXT: [[TMP0:%.*]] = sext i16 [[B:%.*]] to i32 404; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[A:%.*]]) 405; CHECK-NEXT: ret i32 [[TMP1]] 406; 407entry: 408 %conv = sext i32 %a to i64 409 %conv1 = sext i16 %b to i64 410 %add = add i64 %conv1, %conv 411 %0 = icmp slt i64 %add, 2147483647 412 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 413 %1 = icmp sgt i64 %spec.store.select, -2147483648 414 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 415 %conv7 = trunc i64 %spec.store.select8 to i32 416 ret i32 %conv7 417} 418 419define i8 @sadd_sat8_ext8(i8 %a, i16 %b) { 420; CHECK-LABEL: @sadd_sat8_ext8( 421; CHECK-NEXT: entry: 422; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 423; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32 424; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]] 425; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ADD]], 127 426; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 127 427; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -128 428; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -128 429; CHECK-NEXT: [[CONV7:%.*]] = trunc i32 [[SPEC_STORE_SELECT8]] to i8 430; CHECK-NEXT: ret i8 [[CONV7]] 431; 432entry: 433 %conv = sext i8 %a to i32 434 %conv1 = sext i16 %b to i32 435 %add = add i32 %conv1, %conv 436 %0 = icmp slt i32 %add, 127 437 %spec.store.select = select i1 %0, i32 %add, i32 127 438 %1 = icmp sgt i32 %spec.store.select, -128 439 %spec.store.select8 = select i1 %1, i32 %spec.store.select, i32 -128 440 %conv7 = trunc i32 %spec.store.select8 to i8 441 ret i8 %conv7 442} 443 444define i32 @sadd_sat32_zext(i32 %a, i32 %b) { 445; CHECK-LABEL: @sadd_sat32_zext( 446; CHECK-NEXT: entry: 447; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[A:%.*]] to i64 448; CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[B:%.*]] to i64 449; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[CONV1]], [[CONV]] 450; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[ADD]], 2147483647 451; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647 452; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT]] to i32 453; CHECK-NEXT: ret i32 [[CONV7]] 454; 455entry: 456 %conv = zext i32 %a to i64 457 %conv1 = zext i32 %b to i64 458 %add = add i64 %conv1, %conv 459 %0 = icmp slt i64 %add, 2147483647 460 %spec.store.select = select i1 %0, i64 %add, i64 2147483647 461 %1 = icmp sgt i64 %spec.store.select, -2147483648 462 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648 463 %conv7 = trunc i64 %spec.store.select8 to i32 464 ret i32 %conv7 465} 466 467define i32 @sadd_sat32_maxmin(i32 %a, i32 %b) { 468; CHECK-LABEL: @sadd_sat32_maxmin( 469; CHECK-NEXT: entry: 470; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 471; CHECK-NEXT: ret i32 [[TMP0]] 472; 473entry: 474 %conv = sext i32 %a to i64 475 %conv1 = sext i32 %b to i64 476 %add = add i64 %conv1, %conv 477 %0 = icmp sgt i64 %add, -2147483648 478 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 479 %1 = icmp slt i64 %spec.store.select, 2147483647 480 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 481 %conv7 = trunc i64 %spec.store.select8 to i32 482 ret i32 %conv7 483} 484 485define i64 @sadd_sat32_notrunc(i32 %a, i32 %b) { 486; CHECK-LABEL: @sadd_sat32_notrunc( 487; CHECK-NEXT: entry: 488; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 489; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64 490; CHECK-NEXT: ret i64 [[SPEC_STORE_SELECT8]] 491; 492entry: 493 %conv = sext i32 %a to i64 494 %conv1 = sext i32 %b to i64 495 %add = add i64 %conv1, %conv 496 %0 = icmp sgt i64 %add, -2147483648 497 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648 498 %1 = icmp slt i64 %spec.store.select, 2147483647 499 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647 500 ret i64 %spec.store.select8 501} 502 503declare void @use64(i64) 504