1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4define i32 @uadd(i32 %x, i32 %y) { 5; CHECK-LABEL: @uadd( 6; CHECK-NEXT: [[S:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 7; CHECK-NEXT: ret i32 [[S]] 8; 9 %ao = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 10 %o = extractvalue { i32, i1 } %ao, 1 11 %a = extractvalue { i32, i1 } %ao, 0 12 %s = select i1 %o, i32 -1, i32 %a 13 ret i32 %s 14} 15 16define i32 @usub(i32 %x, i32 %y) { 17; CHECK-LABEL: @usub( 18; CHECK-NEXT: [[S:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 19; CHECK-NEXT: ret i32 [[S]] 20; 21 %ao = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y) 22 %o = extractvalue { i32, i1 } %ao, 1 23 %a = extractvalue { i32, i1 } %ao, 0 24 %s = select i1 %o, i32 0, i32 %a 25 ret i32 %s 26} 27 28 29define i8 @sadd_x_lt_min(i8 %x, i8 %y) { 30; CHECK-LABEL: @sadd_x_lt_min( 31; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 32; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 33; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 34; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 0 35; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 36; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 37; CHECK-NEXT: ret i8 [[R]] 38; 39 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 40 %o = extractvalue { i8, i1 } %ao, 1 41 %a = extractvalue { i8, i1 } %ao, 0 42 %c = icmp slt i8 %x, 0 43 %s = select i1 %c, i8 127, i8 -128 44 %r = select i1 %o, i8 %s, i8 %a 45 ret i8 %r 46} 47 48define i8 @sadd_x_lt_max(i8 %x, i8 %y) { 49; CHECK-LABEL: @sadd_x_lt_max( 50; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 51; CHECK-NEXT: ret i8 [[R]] 52; 53 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 54 %o = extractvalue { i8, i1 } %ao, 1 55 %a = extractvalue { i8, i1 } %ao, 0 56 %c = icmp slt i8 %x, 0 57 %s = select i1 %c, i8 -128, i8 127 58 %r = select i1 %o, i8 %s, i8 %a 59 ret i8 %r 60} 61 62define i8 @sadd_x_le_min(i8 %x, i8 %y) { 63; CHECK-LABEL: @sadd_x_le_min( 64; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 65; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 66; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 67; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 1 68; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 69; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 70; CHECK-NEXT: ret i8 [[R]] 71; 72 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 73 %o = extractvalue { i8, i1 } %ao, 1 74 %a = extractvalue { i8, i1 } %ao, 0 75 %c = icmp sle i8 %x, 0 76 %s = select i1 %c, i8 127, i8 -128 77 %r = select i1 %o, i8 %s, i8 %a 78 ret i8 %r 79} 80 81define i8 @sadd_x_le_max(i8 %x, i8 %y) { 82; CHECK-LABEL: @sadd_x_le_max( 83; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 84; CHECK-NEXT: ret i8 [[R]] 85; 86 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 87 %o = extractvalue { i8, i1 } %ao, 1 88 %a = extractvalue { i8, i1 } %ao, 0 89 %c = icmp sle i8 %x, 0 90 %s = select i1 %c, i8 -128, i8 127 91 %r = select i1 %o, i8 %s, i8 %a 92 ret i8 %r 93} 94 95define i8 @sadd_x_gt_min(i8 %x, i8 %y) { 96; CHECK-LABEL: @sadd_x_gt_min( 97; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 98; CHECK-NEXT: ret i8 [[R]] 99; 100 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 101 %o = extractvalue { i8, i1 } %ao, 1 102 %a = extractvalue { i8, i1 } %ao, 0 103 %c = icmp sgt i8 %x, 0 104 %s = select i1 %c, i8 127, i8 -128 105 %r = select i1 %o, i8 %s, i8 %a 106 ret i8 %r 107} 108 109define i8 @sadd_x_gt_max(i8 %x, i8 %y) { 110; CHECK-LABEL: @sadd_x_gt_max( 111; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 112; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 113; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 114; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], 0 115; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 116; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 117; CHECK-NEXT: ret i8 [[R]] 118; 119 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 120 %o = extractvalue { i8, i1 } %ao, 1 121 %a = extractvalue { i8, i1 } %ao, 0 122 %c = icmp sgt i8 %x, 0 123 %s = select i1 %c, i8 -128, i8 127 124 %r = select i1 %o, i8 %s, i8 %a 125 ret i8 %r 126} 127 128define i8 @sadd_x_ge_min(i8 %x, i8 %y) { 129; CHECK-LABEL: @sadd_x_ge_min( 130; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 131; CHECK-NEXT: ret i8 [[R]] 132; 133 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 134 %o = extractvalue { i8, i1 } %ao, 1 135 %a = extractvalue { i8, i1 } %ao, 0 136 %c = icmp sge i8 %x, 0 137 %s = select i1 %c, i8 127, i8 -128 138 %r = select i1 %o, i8 %s, i8 %a 139 ret i8 %r 140} 141 142define i8 @sadd_x_ge_max(i8 %x, i8 %y) { 143; CHECK-LABEL: @sadd_x_ge_max( 144; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 145; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 146; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 147; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], -1 148; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 149; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 150; CHECK-NEXT: ret i8 [[R]] 151; 152 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 153 %o = extractvalue { i8, i1 } %ao, 1 154 %a = extractvalue { i8, i1 } %ao, 0 155 %c = icmp sge i8 %x, 0 156 %s = select i1 %c, i8 -128, i8 127 157 %r = select i1 %o, i8 %s, i8 %a 158 ret i8 %r 159} 160 161 162define i8 @sadd_y_lt_min(i8 %x, i8 %y) { 163; CHECK-LABEL: @sadd_y_lt_min( 164; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 165; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 166; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 167; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 0 168; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 169; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 170; CHECK-NEXT: ret i8 [[R]] 171; 172 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 173 %o = extractvalue { i8, i1 } %ao, 1 174 %a = extractvalue { i8, i1 } %ao, 0 175 %c = icmp slt i8 %y, 0 176 %s = select i1 %c, i8 127, i8 -128 177 %r = select i1 %o, i8 %s, i8 %a 178 ret i8 %r 179} 180 181define i8 @sadd_y_lt_max(i8 %x, i8 %y) { 182; CHECK-LABEL: @sadd_y_lt_max( 183; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 184; CHECK-NEXT: ret i8 [[R]] 185; 186 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 187 %o = extractvalue { i8, i1 } %ao, 1 188 %a = extractvalue { i8, i1 } %ao, 0 189 %c = icmp slt i8 %y, 0 190 %s = select i1 %c, i8 -128, i8 127 191 %r = select i1 %o, i8 %s, i8 %a 192 ret i8 %r 193} 194 195define i8 @sadd_y_le_min(i8 %x, i8 %y) { 196; CHECK-LABEL: @sadd_y_le_min( 197; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 198; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 199; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 200; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 1 201; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 202; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 203; CHECK-NEXT: ret i8 [[R]] 204; 205 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 206 %o = extractvalue { i8, i1 } %ao, 1 207 %a = extractvalue { i8, i1 } %ao, 0 208 %c = icmp sle i8 %y, 0 209 %s = select i1 %c, i8 127, i8 -128 210 %r = select i1 %o, i8 %s, i8 %a 211 ret i8 %r 212} 213 214define i8 @sadd_y_le_max(i8 %x, i8 %y) { 215; CHECK-LABEL: @sadd_y_le_max( 216; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 217; CHECK-NEXT: ret i8 [[R]] 218; 219 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 220 %o = extractvalue { i8, i1 } %ao, 1 221 %a = extractvalue { i8, i1 } %ao, 0 222 %c = icmp sle i8 %y, 0 223 %s = select i1 %c, i8 -128, i8 127 224 %r = select i1 %o, i8 %s, i8 %a 225 ret i8 %r 226} 227 228define i8 @sadd_y_gt_min(i8 %x, i8 %y) { 229; CHECK-LABEL: @sadd_y_gt_min( 230; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 231; CHECK-NEXT: ret i8 [[R]] 232; 233 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 234 %o = extractvalue { i8, i1 } %ao, 1 235 %a = extractvalue { i8, i1 } %ao, 0 236 %c = icmp sgt i8 %y, 0 237 %s = select i1 %c, i8 127, i8 -128 238 %r = select i1 %o, i8 %s, i8 %a 239 ret i8 %r 240} 241 242define i8 @sadd_y_gt_max(i8 %x, i8 %y) { 243; CHECK-LABEL: @sadd_y_gt_max( 244; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 245; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 246; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 247; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], 0 248; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 249; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 250; CHECK-NEXT: ret i8 [[R]] 251; 252 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 253 %o = extractvalue { i8, i1 } %ao, 1 254 %a = extractvalue { i8, i1 } %ao, 0 255 %c = icmp sgt i8 %y, 0 256 %s = select i1 %c, i8 -128, i8 127 257 %r = select i1 %o, i8 %s, i8 %a 258 ret i8 %r 259} 260 261define i8 @sadd_y_ge_min(i8 %x, i8 %y) { 262; CHECK-LABEL: @sadd_y_ge_min( 263; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 264; CHECK-NEXT: ret i8 [[R]] 265; 266 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 267 %o = extractvalue { i8, i1 } %ao, 1 268 %a = extractvalue { i8, i1 } %ao, 0 269 %c = icmp sge i8 %y, 0 270 %s = select i1 %c, i8 127, i8 -128 271 %r = select i1 %o, i8 %s, i8 %a 272 ret i8 %r 273} 274 275define i8 @sadd_y_ge_max(i8 %x, i8 %y) { 276; CHECK-LABEL: @sadd_y_ge_max( 277; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 278; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 279; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 280; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], -1 281; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 282; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 283; CHECK-NEXT: ret i8 [[R]] 284; 285 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y) 286 %o = extractvalue { i8, i1 } %ao, 1 287 %a = extractvalue { i8, i1 } %ao, 0 288 %c = icmp sge i8 %y, 0 289 %s = select i1 %c, i8 -128, i8 127 290 %r = select i1 %o, i8 %s, i8 %a 291 ret i8 %r 292} 293 294 295 296 297define i8 @ssub_x_lt_min(i8 %x, i8 %y) { 298; CHECK-LABEL: @ssub_x_lt_min( 299; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 300; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 301; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 302; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 0 303; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 304; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 305; CHECK-NEXT: ret i8 [[R]] 306; 307 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 308 %o = extractvalue { i8, i1 } %ao, 1 309 %a = extractvalue { i8, i1 } %ao, 0 310 %c = icmp slt i8 %x, 0 311 %s = select i1 %c, i8 127, i8 -128 312 %r = select i1 %o, i8 %s, i8 %a 313 ret i8 %r 314} 315 316define i8 @ssub_x_lt_max(i8 %x, i8 %y) { 317; CHECK-LABEL: @ssub_x_lt_max( 318; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 319; CHECK-NEXT: ret i8 [[R]] 320; 321 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 322 %o = extractvalue { i8, i1 } %ao, 1 323 %a = extractvalue { i8, i1 } %ao, 0 324 %c = icmp slt i8 %x, 0 325 %s = select i1 %c, i8 -128, i8 127 326 %r = select i1 %o, i8 %s, i8 %a 327 ret i8 %r 328} 329 330define i8 @ssub_x_le_min(i8 %x, i8 %y) { 331; CHECK-LABEL: @ssub_x_le_min( 332; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 333; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 334; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 335; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 1 336; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 337; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 338; CHECK-NEXT: ret i8 [[R]] 339; 340 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 341 %o = extractvalue { i8, i1 } %ao, 1 342 %a = extractvalue { i8, i1 } %ao, 0 343 %c = icmp sle i8 %x, 0 344 %s = select i1 %c, i8 127, i8 -128 345 %r = select i1 %o, i8 %s, i8 %a 346 ret i8 %r 347} 348 349define i8 @ssub_x_le_max(i8 %x, i8 %y) { 350; CHECK-LABEL: @ssub_x_le_max( 351; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 352; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 353; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 354; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 1 355; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 356; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 357; CHECK-NEXT: ret i8 [[R]] 358; 359 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 360 %o = extractvalue { i8, i1 } %ao, 1 361 %a = extractvalue { i8, i1 } %ao, 0 362 %c = icmp sle i8 %x, 0 363 %s = select i1 %c, i8 -128, i8 127 364 %r = select i1 %o, i8 %s, i8 %a 365 ret i8 %r 366} 367 368define i8 @ssub_x_lt2_min(i8 %x, i8 %y) { 369; CHECK-LABEL: @ssub_x_lt2_min( 370; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 371; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 372; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 373; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], -1 374; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 375; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 376; CHECK-NEXT: ret i8 [[R]] 377; 378 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 379 %o = extractvalue { i8, i1 } %ao, 1 380 %a = extractvalue { i8, i1 } %ao, 0 381 %c = icmp slt i8 %x, -1 382 %s = select i1 %c, i8 127, i8 -128 383 %r = select i1 %o, i8 %s, i8 %a 384 ret i8 %r 385} 386 387define i8 @ssub_x_lt2_max(i8 %x, i8 %y) { 388; CHECK-LABEL: @ssub_x_lt2_max( 389; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 390; CHECK-NEXT: ret i8 [[R]] 391; 392 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 393 %o = extractvalue { i8, i1 } %ao, 1 394 %a = extractvalue { i8, i1 } %ao, 0 395 %c = icmp slt i8 %x, -1 396 %s = select i1 %c, i8 -128, i8 127 397 %r = select i1 %o, i8 %s, i8 %a 398 ret i8 %r 399} 400 401define i8 @ssub_x_gt_min(i8 %x, i8 %y) { 402; CHECK-LABEL: @ssub_x_gt_min( 403; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 404; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 405; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 406; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], 0 407; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 408; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 409; CHECK-NEXT: ret i8 [[R]] 410; 411 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 412 %o = extractvalue { i8, i1 } %ao, 1 413 %a = extractvalue { i8, i1 } %ao, 0 414 %c = icmp sgt i8 %x, 0 415 %s = select i1 %c, i8 127, i8 -128 416 %r = select i1 %o, i8 %s, i8 %a 417 ret i8 %r 418} 419 420define i8 @ssub_x_gt_max(i8 %x, i8 %y) { 421; CHECK-LABEL: @ssub_x_gt_max( 422; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 423; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 424; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 425; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], 0 426; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 427; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 428; CHECK-NEXT: ret i8 [[R]] 429; 430 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 431 %o = extractvalue { i8, i1 } %ao, 1 432 %a = extractvalue { i8, i1 } %ao, 0 433 %c = icmp sgt i8 %x, 0 434 %s = select i1 %c, i8 -128, i8 127 435 %r = select i1 %o, i8 %s, i8 %a 436 ret i8 %r 437} 438 439define i8 @ssub_x_ge_min(i8 %x, i8 %y) { 440; CHECK-LABEL: @ssub_x_ge_min( 441; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 442; CHECK-NEXT: ret i8 [[R]] 443; 444 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 445 %o = extractvalue { i8, i1 } %ao, 1 446 %a = extractvalue { i8, i1 } %ao, 0 447 %c = icmp sge i8 %x, 0 448 %s = select i1 %c, i8 127, i8 -128 449 %r = select i1 %o, i8 %s, i8 %a 450 ret i8 %r 451} 452 453define i8 @ssub_x_ge_max(i8 %x, i8 %y) { 454; CHECK-LABEL: @ssub_x_ge_max( 455; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 456; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 457; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 458; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], -1 459; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 460; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 461; CHECK-NEXT: ret i8 [[R]] 462; 463 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 464 %o = extractvalue { i8, i1 } %ao, 1 465 %a = extractvalue { i8, i1 } %ao, 0 466 %c = icmp sge i8 %x, 0 467 %s = select i1 %c, i8 -128, i8 127 468 %r = select i1 %o, i8 %s, i8 %a 469 ret i8 %r 470} 471 472define i8 @ssub_x_gt2_min(i8 %x, i8 %y) { 473; CHECK-LABEL: @ssub_x_gt2_min( 474; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 475; CHECK-NEXT: ret i8 [[R]] 476; 477 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 478 %o = extractvalue { i8, i1 } %ao, 1 479 %a = extractvalue { i8, i1 } %ao, 0 480 %c = icmp sgt i8 %x, -2 481 %s = select i1 %c, i8 127, i8 -128 482 %r = select i1 %o, i8 %s, i8 %a 483 ret i8 %r 484} 485 486define i8 @ssub_x_gt2_max(i8 %x, i8 %y) { 487; CHECK-LABEL: @ssub_x_gt2_max( 488; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 489; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 490; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 491; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], -2 492; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 493; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 494; CHECK-NEXT: ret i8 [[R]] 495; 496 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 497 %o = extractvalue { i8, i1 } %ao, 1 498 %a = extractvalue { i8, i1 } %ao, 0 499 %c = icmp sgt i8 %x, -2 500 %s = select i1 %c, i8 -128, i8 127 501 %r = select i1 %o, i8 %s, i8 %a 502 ret i8 %r 503} 504 505 506define i8 @ssub_y_lt_min(i8 %x, i8 %y) { 507; CHECK-LABEL: @ssub_y_lt_min( 508; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 509; CHECK-NEXT: ret i8 [[R]] 510; 511 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 512 %o = extractvalue { i8, i1 } %ao, 1 513 %a = extractvalue { i8, i1 } %ao, 0 514 %c = icmp slt i8 %y, 0 515 %s = select i1 %c, i8 127, i8 -128 516 %r = select i1 %o, i8 %s, i8 %a 517 ret i8 %r 518} 519 520define i8 @ssub_y_lt_max(i8 %x, i8 %y) { 521; CHECK-LABEL: @ssub_y_lt_max( 522; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 523; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 524; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 525; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 0 526; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 527; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 528; CHECK-NEXT: ret i8 [[R]] 529; 530 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 531 %o = extractvalue { i8, i1 } %ao, 1 532 %a = extractvalue { i8, i1 } %ao, 0 533 %c = icmp slt i8 %y, 0 534 %s = select i1 %c, i8 -128, i8 127 535 %r = select i1 %o, i8 %s, i8 %a 536 ret i8 %r 537} 538 539define i8 @ssub_y_le_min(i8 %x, i8 %y) { 540; CHECK-LABEL: @ssub_y_le_min( 541; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 542; CHECK-NEXT: ret i8 [[R]] 543; 544 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 545 %o = extractvalue { i8, i1 } %ao, 1 546 %a = extractvalue { i8, i1 } %ao, 0 547 %c = icmp sle i8 %y, 0 548 %s = select i1 %c, i8 127, i8 -128 549 %r = select i1 %o, i8 %s, i8 %a 550 ret i8 %r 551} 552 553define i8 @ssub_y_le_max(i8 %x, i8 %y) { 554; CHECK-LABEL: @ssub_y_le_max( 555; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 556; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 557; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 558; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 1 559; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127 560; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 561; CHECK-NEXT: ret i8 [[R]] 562; 563 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 564 %o = extractvalue { i8, i1 } %ao, 1 565 %a = extractvalue { i8, i1 } %ao, 0 566 %c = icmp sle i8 %y, 0 567 %s = select i1 %c, i8 -128, i8 127 568 %r = select i1 %o, i8 %s, i8 %a 569 ret i8 %r 570} 571 572define i8 @ssub_y_gt_min(i8 %x, i8 %y) { 573; CHECK-LABEL: @ssub_y_gt_min( 574; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 575; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 576; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 577; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], 0 578; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 579; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 580; CHECK-NEXT: ret i8 [[R]] 581; 582 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 583 %o = extractvalue { i8, i1 } %ao, 1 584 %a = extractvalue { i8, i1 } %ao, 0 585 %c = icmp sgt i8 %y, 0 586 %s = select i1 %c, i8 127, i8 -128 587 %r = select i1 %o, i8 %s, i8 %a 588 ret i8 %r 589} 590 591define i8 @ssub_y_gt_max(i8 %x, i8 %y) { 592; CHECK-LABEL: @ssub_y_gt_max( 593; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 594; CHECK-NEXT: ret i8 [[R]] 595; 596 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 597 %o = extractvalue { i8, i1 } %ao, 1 598 %a = extractvalue { i8, i1 } %ao, 0 599 %c = icmp sgt i8 %y, 0 600 %s = select i1 %c, i8 -128, i8 127 601 %r = select i1 %o, i8 %s, i8 %a 602 ret i8 %r 603} 604 605define i8 @ssub_y_ge_min(i8 %x, i8 %y) { 606; CHECK-LABEL: @ssub_y_ge_min( 607; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 608; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1 609; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0 610; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], -1 611; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128 612; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]] 613; CHECK-NEXT: ret i8 [[R]] 614; 615 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 616 %o = extractvalue { i8, i1 } %ao, 1 617 %a = extractvalue { i8, i1 } %ao, 0 618 %c = icmp sge i8 %y, 0 619 %s = select i1 %c, i8 127, i8 -128 620 %r = select i1 %o, i8 %s, i8 %a 621 ret i8 %r 622} 623 624define i8 @ssub_y_ge_max(i8 %x, i8 %y) { 625; CHECK-LABEL: @ssub_y_ge_max( 626; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 627; CHECK-NEXT: ret i8 [[R]] 628; 629 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y) 630 %o = extractvalue { i8, i1 } %ao, 1 631 %a = extractvalue { i8, i1 } %ao, 0 632 %c = icmp sge i8 %y, 0 633 %s = select i1 %c, i8 -128, i8 127 634 %r = select i1 %o, i8 %s, i8 %a 635 ret i8 %r 636} 637 638 639define i32 @sadd_i32(i32 %x, i32 %y) { 640; CHECK-LABEL: @sadd_i32( 641; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 642; CHECK-NEXT: ret i32 [[R]] 643; 644 %ao = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y) 645 %o = extractvalue { i32, i1 } %ao, 1 646 %a = extractvalue { i32, i1 } %ao, 0 647 %c = icmp slt i32 %x, 0 648 %s = select i1 %c, i32 -2147483648, i32 2147483647 649 %r = select i1 %o, i32 %s, i32 %a 650 ret i32 %r 651} 652 653define i32 @ssub_i32(i32 %x, i32 %y) { 654; CHECK-LABEL: @ssub_i32( 655; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 656; CHECK-NEXT: ret i32 [[R]] 657; 658 %ao = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y) 659 %o = extractvalue { i32, i1 } %ao, 1 660 %a = extractvalue { i32, i1 } %ao, 0 661 %c = icmp slt i32 %x, 0 662 %s = select i1 %c, i32 -2147483648, i32 2147483647 663 %r = select i1 %o, i32 %s, i32 %a 664 ret i32 %r 665} 666 667define i32 @sadd_bounds(i32 %x, i32 %y) { 668; CHECK-LABEL: @sadd_bounds( 669; CHECK-NEXT: [[AO:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 670; CHECK-NEXT: [[O:%.*]] = extractvalue { i32, i1 } [[AO]], 1 671; CHECK-NEXT: [[A:%.*]] = extractvalue { i32, i1 } [[AO]], 0 672; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X]], 0 673; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 -128, i32 127 674; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i32 [[S]], i32 [[A]] 675; CHECK-NEXT: ret i32 [[R]] 676; 677 %ao = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y) 678 %o = extractvalue { i32, i1 } %ao, 1 679 %a = extractvalue { i32, i1 } %ao, 0 680 %c = icmp slt i32 %x, 0 681 %s = select i1 %c, i32 -128, i32 127 682 %r = select i1 %o, i32 %s, i32 %a 683 ret i32 %r 684} 685 686define i32 @ssub_bounds(i32 %x, i32 %y) { 687; CHECK-LABEL: @ssub_bounds( 688; CHECK-NEXT: [[AO:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 689; CHECK-NEXT: [[O:%.*]] = extractvalue { i32, i1 } [[AO]], 1 690; CHECK-NEXT: [[A:%.*]] = extractvalue { i32, i1 } [[AO]], 0 691; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X]], 0 692; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 -128, i32 127 693; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i32 [[S]], i32 [[A]] 694; CHECK-NEXT: ret i32 [[R]] 695; 696 %ao = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y) 697 %o = extractvalue { i32, i1 } %ao, 1 698 %a = extractvalue { i32, i1 } %ao, 0 699 %c = icmp slt i32 %x, 0 700 %s = select i1 %c, i32 -128, i32 127 701 %r = select i1 %o, i32 %s, i32 %a 702 ret i32 %r 703} 704 705declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %0, i32 %1) 706declare { i32, i1 } @llvm.usub.with.overflow.i32(i32 %0, i32 %1) 707declare { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %0, i8 %1) 708declare { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %0, i8 %1) 709declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %0, i32 %1) 710declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %0, i32 %1) 711