1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -S < %s | FileCheck %s 3; RUN: opt -enable-debugify -passes='require<profile-summary>,function(codegenprepare)' -S < %s 2>&1 | FileCheck %s -check-prefix=DEBUG 4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6target triple = "x86_64-apple-darwin10.0.0" 7 8define i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp { 9; CHECK-LABEL: @uaddo1_overflow_used( 10; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 11; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 12; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 13; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 14; CHECK-NEXT: ret i64 [[Q]] 15; 16 %add = add i64 %b, %a 17 %cmp = icmp ult i64 %add, %a 18 %Q = select i1 %cmp, i64 %b, i64 42 19 ret i64 %Q 20} 21 22define i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp { 23; CHECK-LABEL: @uaddo1_math_overflow_used( 24; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 25; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 26; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 27; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 28; CHECK-NEXT: store i64 [[MATH]], ptr [[RES:%.*]] 29; CHECK-NEXT: ret i64 [[Q]] 30; 31 %add = add i64 %b, %a 32 %cmp = icmp ult i64 %add, %a 33 %Q = select i1 %cmp, i64 %b, i64 42 34 store i64 %add, ptr %res 35 ret i64 %Q 36} 37 38define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp { 39; CHECK-LABEL: @uaddo2_overflow_used( 40; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 41; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 42; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 43; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 44; CHECK-NEXT: ret i64 [[Q]] 45; 46 %add = add i64 %b, %a 47 %cmp = icmp ult i64 %add, %b 48 %Q = select i1 %cmp, i64 %b, i64 42 49 ret i64 %Q 50} 51 52define i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp { 53; CHECK-LABEL: @uaddo2_math_overflow_used( 54; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 55; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 56; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 57; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 58; CHECK-NEXT: store i64 [[MATH]], ptr [[RES:%.*]] 59; CHECK-NEXT: ret i64 [[Q]] 60; 61 %add = add i64 %b, %a 62 %cmp = icmp ult i64 %add, %b 63 %Q = select i1 %cmp, i64 %b, i64 42 64 store i64 %add, ptr %res 65 ret i64 %Q 66} 67 68define i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp { 69; CHECK-LABEL: @uaddo3_overflow_used( 70; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 71; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 72; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 73; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 74; CHECK-NEXT: ret i64 [[Q]] 75; 76 %add = add i64 %b, %a 77 %cmp = icmp ugt i64 %b, %add 78 %Q = select i1 %cmp, i64 %b, i64 42 79 ret i64 %Q 80} 81 82define i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp { 83; CHECK-LABEL: @uaddo3_math_overflow_used( 84; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) 85; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 86; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 87; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 88; CHECK-NEXT: store i64 [[MATH]], ptr [[RES:%.*]] 89; CHECK-NEXT: ret i64 [[Q]] 90; 91 %add = add i64 %b, %a 92 %cmp = icmp ugt i64 %b, %add 93 %Q = select i1 %cmp, i64 %b, i64 42 94 store i64 %add, ptr %res 95 ret i64 %Q 96} 97 98; TODO? CGP sinks the compare before we have a chance to form the overflow intrinsic. 99 100define i64 @uaddo4(i64 %a, i64 %b, i1 %c) nounwind ssp { 101; CHECK-LABEL: @uaddo4( 102; CHECK-NEXT: entry: 103; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] 104; CHECK-NEXT: br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]] 105; CHECK: next: 106; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]] 107; CHECK-NEXT: [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42 108; CHECK-NEXT: ret i64 [[Q]] 109; CHECK: exit: 110; CHECK-NEXT: ret i64 0 111; 112entry: 113 %add = add i64 %b, %a 114 %cmp = icmp ugt i64 %b, %add 115 br i1 %c, label %next, label %exit 116 117next: 118 %Q = select i1 %cmp, i64 %b, i64 42 119 ret i64 %Q 120 121exit: 122 ret i64 0 123} 124 125define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp { 126; CHECK-LABEL: @uaddo5( 127; CHECK-NEXT: entry: 128; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] 129; CHECK-NEXT: store i64 [[ADD]], ptr [[PTR:%.*]] 130; CHECK-NEXT: br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]] 131; CHECK: next: 132; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]] 133; CHECK-NEXT: [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42 134; CHECK-NEXT: ret i64 [[Q]] 135; CHECK: exit: 136; CHECK-NEXT: ret i64 0 137; 138entry: 139 %add = add i64 %b, %a 140 store i64 %add, ptr %ptr 141 %cmp = icmp ugt i64 %b, %add 142 br i1 %c, label %next, label %exit 143 144next: 145 %Q = select i1 %cmp, i64 %b, i64 42 146 ret i64 %Q 147 148exit: 149 ret i64 0 150} 151 152; Instcombine folds (a + b <u a) to (a ^ -1 <u b). Make sure we match this 153; pattern as well. 154define i64 @uaddo6_xor(i64 %a, i64 %b) { 155; CHECK-LABEL: @uaddo6_xor( 156; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]) 157; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 158; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 159; CHECK-NEXT: ret i64 [[Q]] 160; 161 %x = xor i64 %a, -1 162 %cmp = icmp ult i64 %x, %b 163 %Q = select i1 %cmp, i64 %b, i64 42 164 ret i64 %Q 165} 166 167define i64 @uaddo6_xor_commuted(i64 %a, i64 %b) { 168; CHECK-LABEL: @uaddo6_xor_commuted( 169; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]) 170; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 171; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 172; CHECK-NEXT: ret i64 [[Q]] 173; 174 %x = xor i64 %a, -1 175 %cmp = icmp ult i64 %x, %b 176 %Q = select i1 %cmp, i64 %b, i64 42 177 ret i64 %Q 178} 179 180declare void @use(i64) 181 182define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) { 183; CHECK-LABEL: @uaddo6_xor_multi_use( 184; CHECK-NEXT: [[X:%.*]] = xor i64 -1, [[A:%.*]] 185; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X]], [[B:%.*]] 186; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 187; CHECK-NEXT: call void @use(i64 [[X]]) 188; CHECK-NEXT: ret i64 [[Q]] 189; 190 %x = xor i64 -1, %a 191 %cmp = icmp ult i64 %x, %b 192 %Q = select i1 %cmp, i64 %b, i64 42 193 call void @use(i64 %x) 194 ret i64 %Q 195} 196 197; Make sure we do not use the XOR binary operator as insert point, as it may 198; come before the second operand of the overflow intrinsic. 199define i1 @uaddo6_xor_op_after_XOR(i32 %a, ptr %b.ptr) { 200; CHECK-LABEL: @uaddo6_xor_op_after_XOR( 201; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 8 202; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B]]) 203; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 204; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true 205; CHECK-NEXT: ret i1 [[OV]] 206; 207 %x = xor i32 %a, -1 208 %b = load i32, ptr %b.ptr, align 8 209 %cmp14 = icmp ugt i32 %b, %x 210 %ov = xor i1 %cmp14, true 211 ret i1 %ov 212} 213 214; When adding 1, the general pattern for add-overflow may be different due to icmp canonicalization. 215; PR31754: https://bugs.llvm.org/show_bug.cgi?id=31754 216 217define i1 @uaddo_i64_increment(i64 %x, ptr %p) { 218; CHECK-LABEL: @uaddo_i64_increment( 219; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1) 220; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 221; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 222; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 223; CHECK-NEXT: ret i1 [[OV1]] 224; 225 %a = add i64 %x, 1 226 %ov = icmp eq i64 %a, 0 227 store i64 %a, ptr %p 228 ret i1 %ov 229} 230 231define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) { 232; CHECK-LABEL: @uaddo_i8_increment_noncanonical_1( 233; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 1, i8 [[X:%.*]]) 234; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 235; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 236; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]] 237; CHECK-NEXT: ret i1 [[OV1]] 238; 239 %a = add i8 1, %x ; commute 240 %ov = icmp eq i8 %a, 0 241 store i8 %a, ptr %p 242 ret i1 %ov 243} 244 245define i1 @uaddo_i32_increment_noncanonical_2(i32 %x, ptr %p) { 246; CHECK-LABEL: @uaddo_i32_increment_noncanonical_2( 247; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 1) 248; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 249; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 250; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] 251; CHECK-NEXT: ret i1 [[OV1]] 252; 253 %a = add i32 %x, 1 254 %ov = icmp eq i32 0, %a ; commute 255 store i32 %a, ptr %p 256 ret i1 %ov 257} 258 259define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) { 260; CHECK-LABEL: @uaddo_i16_increment_noncanonical_3( 261; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 1, i16 [[X:%.*]]) 262; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 263; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 264; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]] 265; CHECK-NEXT: ret i1 [[OV1]] 266; 267 %a = add i16 1, %x ; commute 268 %ov = icmp eq i16 0, %a ; commute 269 store i16 %a, ptr %p 270 ret i1 %ov 271} 272 273; The overflow check may be against the input rather than the sum. 274 275define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) { 276; CHECK-LABEL: @uaddo_i64_increment_alt( 277; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1) 278; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 279; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 280; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 281; CHECK-NEXT: ret i1 [[OV1]] 282; 283 %a = add i64 %x, 1 284 store i64 %a, ptr %p 285 %ov = icmp eq i64 %x, -1 286 ret i1 %ov 287} 288 289; Make sure insertion is done correctly based on dominance. 290 291define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) { 292; CHECK-LABEL: @uaddo_i64_increment_alt_dom( 293; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1) 294; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 295; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 296; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 297; CHECK-NEXT: ret i1 [[OV1]] 298; 299 %ov = icmp eq i64 %x, -1 300 %a = add i64 %x, 1 301 store i64 %a, ptr %p 302 ret i1 %ov 303} 304 305; The overflow check may be against the input rather than the sum. 306 307define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) { 308; CHECK-LABEL: @uaddo_i64_decrement_alt( 309; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1) 310; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 311; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 312; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 313; CHECK-NEXT: ret i1 [[OV1]] 314; 315 %a = add i64 %x, -1 316 store i64 %a, ptr %p 317 %ov = icmp ne i64 %x, 0 318 ret i1 %ov 319} 320 321; Make sure insertion is done correctly based on dominance. 322 323define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) { 324; CHECK-LABEL: @uaddo_i64_decrement_alt_dom( 325; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1) 326; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 327; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 328; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 329; CHECK-NEXT: ret i1 [[OV1]] 330; 331 %ov = icmp ne i64 %x, 0 332 %a = add i64 %x, -1 333 store i64 %a, ptr %p 334 ret i1 %ov 335} 336 337; No transform for illegal types. 338 339define i1 @uaddo_i42_increment_illegal_type(i42 %x, ptr %p) { 340; CHECK-LABEL: @uaddo_i42_increment_illegal_type( 341; CHECK-NEXT: [[A:%.*]] = add i42 [[X:%.*]], 1 342; CHECK-NEXT: [[OV:%.*]] = icmp eq i42 [[A]], 0 343; CHECK-NEXT: store i42 [[A]], ptr [[P:%.*]] 344; CHECK-NEXT: ret i1 [[OV]] 345; 346 %a = add i42 %x, 1 347 %ov = icmp eq i42 %a, 0 348 store i42 %a, ptr %p 349 ret i1 %ov 350} 351 352define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) { 353; CHECK-LABEL: @usubo_ult_i64_overflow_used( 354; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]) 355; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 356; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 357; CHECK-NEXT: ret i1 [[OV1]] 358; 359 %s = sub i64 %x, %y 360 %ov = icmp ult i64 %x, %y 361 ret i1 %ov 362} 363 364define i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) { 365; CHECK-LABEL: @usubo_ult_i64_math_overflow_used( 366; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]) 367; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 368; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 369; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 370; CHECK-NEXT: ret i1 [[OV1]] 371; 372 %s = sub i64 %x, %y 373 store i64 %s, ptr %p 374 %ov = icmp ult i64 %x, %y 375 ret i1 %ov 376} 377 378; Verify insertion point for single-BB. Toggle predicate. 379 380define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) { 381; CHECK-LABEL: @usubo_ugt_i32( 382; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 383; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 384; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 385; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] 386; CHECK-NEXT: ret i1 [[OV1]] 387; 388 %ov = icmp ugt i32 %y, %x 389 %s = sub i32 %x, %y 390 store i32 %s, ptr %p 391 ret i1 %ov 392} 393 394; Constant operand should match. 395 396define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) { 397; CHECK-LABEL: @usubo_ugt_constant_op0_i8( 398; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]]) 399; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 400; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 401; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]] 402; CHECK-NEXT: ret i1 [[OV1]] 403; 404 %s = sub i8 42, %x 405 %ov = icmp ugt i8 %x, 42 406 store i8 %s, ptr %p 407 ret i1 %ov 408} 409 410; Compare with constant operand 0 is canonicalized by commuting, but verify match for non-canonical form. 411 412define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) { 413; CHECK-LABEL: @usubo_ult_constant_op0_i16( 414; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]]) 415; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 416; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 417; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]] 418; CHECK-NEXT: ret i1 [[OV1]] 419; 420 %s = sub i16 43, %x 421 %ov = icmp ult i16 43, %x 422 store i16 %s, ptr %p 423 ret i1 %ov 424} 425 426; Subtract with constant operand 1 is canonicalized to add. 427 428define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) { 429; CHECK-LABEL: @usubo_ult_constant_op1_i16( 430; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44) 431; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 432; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 433; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]] 434; CHECK-NEXT: ret i1 [[OV1]] 435; 436 %s = add i16 %x, -44 437 %ov = icmp ult i16 %x, 44 438 store i16 %s, ptr %p 439 ret i1 %ov 440} 441 442define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) { 443; CHECK-LABEL: @usubo_ugt_constant_op1_i8( 444; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45) 445; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 446; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 447; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]] 448; CHECK-NEXT: ret i1 [[OV1]] 449; 450 %ov = icmp ugt i8 45, %x 451 %s = add i8 %x, -45 452 store i8 %s, ptr %p 453 ret i1 %ov 454} 455 456; Special-case: subtract 1 changes the compare predicate and constant. 457 458define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) { 459; CHECK-LABEL: @usubo_eq_constant1_op1_i32( 460; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1) 461; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 462; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 463; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] 464; CHECK-NEXT: ret i1 [[OV1]] 465; 466 %s = add i32 %x, -1 467 %ov = icmp eq i32 %x, 0 468 store i32 %s, ptr %p 469 ret i1 %ov 470} 471 472; Special-case: subtract from 0 (negate) changes the compare predicate. 473 474define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) { 475; CHECK-LABEL: @usubo_ne_constant0_op1_i32( 476; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 [[X:%.*]]) 477; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 478; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 479; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] 480; CHECK-NEXT: ret i1 [[OV1]] 481; 482 %s = sub i32 0, %x 483 %ov = icmp ne i32 %x, 0 484 store i32 %s, ptr %p 485 ret i1 %ov 486} 487 488; This used to verify insertion point for multi-BB, but now we just bail out. 489 490declare void @call(i1) 491 492define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) { 493; CHECK-LABEL: @usubo_ult_sub_dominates_i64( 494; CHECK-NEXT: entry: 495; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] 496; CHECK: t: 497; CHECK-NEXT: [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]] 498; CHECK-NEXT: store i64 [[S]], ptr [[P:%.*]] 499; CHECK-NEXT: br i1 [[COND]], label [[END:%.*]], label [[F]] 500; CHECK: f: 501; CHECK-NEXT: ret i1 [[COND]] 502; CHECK: end: 503; CHECK-NEXT: [[OV:%.*]] = icmp ult i64 [[X]], [[Y]] 504; CHECK-NEXT: ret i1 [[OV]] 505; 506entry: 507 br i1 %cond, label %t, label %f 508 509t: 510 %s = sub i64 %x, %y 511 store i64 %s, ptr %p 512 br i1 %cond, label %end, label %f 513 514f: 515 ret i1 %cond 516 517end: 518 %ov = icmp ult i64 %x, %y 519 ret i1 %ov 520} 521 522define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) { 523; CHECK-LABEL: @usubo_ult_cmp_dominates_i64( 524; CHECK-NEXT: entry: 525; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] 526; CHECK: t: 527; CHECK-NEXT: [[OV:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]] 528; CHECK-NEXT: call void @call(i1 [[OV]]) 529; CHECK-NEXT: br i1 [[OV]], label [[END:%.*]], label [[F]] 530; CHECK: f: 531; CHECK-NEXT: ret i1 [[COND]] 532; CHECK: end: 533; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]]) 534; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 535; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 536; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] 537; CHECK-NEXT: ret i1 [[OV1]] 538; 539entry: 540 br i1 %cond, label %t, label %f 541 542t: 543 %ov = icmp ult i64 %x, %y 544 call void @call(i1 %ov) 545 br i1 %ov, label %end, label %f 546 547f: 548 ret i1 %cond 549 550end: 551 %s = sub i64 %x, %y 552 store i64 %s, ptr %p 553 ret i1 %ov 554} 555 556; Verify that crazy/non-canonical code does not crash. 557 558define void @bar() { 559; CHECK-LABEL: @bar( 560; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 1, -1 561; CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8 562; CHECK-NEXT: unreachable 563; 564 %cmp = icmp eq i64 1, -1 565 %frombool = zext i1 %cmp to i8 566 unreachable 567} 568 569define void @foo() { 570; CHECK-LABEL: @foo( 571; CHECK-NEXT: [[SUB:%.*]] = add nsw i64 1, 1 572; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[SUB]] to i32 573; CHECK-NEXT: unreachable 574; 575 %sub = add nsw i64 1, 1 576 %conv = trunc i64 %sub to i32 577 unreachable 578} 579 580; Similarly for usubo. 581 582define i1 @bar2() { 583; CHECK-LABEL: @bar2( 584; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 1, 0 585; CHECK-NEXT: ret i1 [[CMP]] 586; 587 %cmp = icmp eq i64 1, 0 588 ret i1 %cmp 589} 590 591define i64 @foo2(ptr %p) { 592; CHECK-LABEL: @foo2( 593; CHECK-NEXT: [[SUB:%.*]] = add nsw i64 1, -1 594; CHECK-NEXT: ret i64 [[SUB]] 595; 596 %sub = add nsw i64 1, -1 597 ret i64 %sub 598} 599 600; Avoid hoisting a math op into a dominating block which would 601; increase the critical path. 602 603define void @PR41129(ptr %p64) { 604; CHECK-LABEL: @PR41129( 605; CHECK-NEXT: entry: 606; CHECK-NEXT: [[KEY:%.*]] = load i64, ptr [[P64:%.*]], align 8 607; CHECK-NEXT: [[COND17:%.*]] = icmp eq i64 [[KEY]], 0 608; CHECK-NEXT: br i1 [[COND17]], label [[TRUE:%.*]], label [[FALSE:%.*]] 609; CHECK: false: 610; CHECK-NEXT: [[ANDVAL:%.*]] = and i64 [[KEY]], 7 611; CHECK-NEXT: store i64 [[ANDVAL]], ptr [[P64]] 612; CHECK-NEXT: br label [[EXIT:%.*]] 613; CHECK: true: 614; CHECK-NEXT: [[SVALUE:%.*]] = add i64 [[KEY]], -1 615; CHECK-NEXT: store i64 [[SVALUE]], ptr [[P64]] 616; CHECK-NEXT: br label [[EXIT]] 617; CHECK: exit: 618; CHECK-NEXT: ret void 619; 620entry: 621 %key = load i64, ptr %p64, align 8 622 %cond17 = icmp eq i64 %key, 0 623 br i1 %cond17, label %true, label %false 624 625false: 626 %andval = and i64 %key, 7 627 store i64 %andval, ptr %p64 628 br label %exit 629 630true: 631 %svalue = add i64 %key, -1 632 store i64 %svalue, ptr %p64 633 br label %exit 634 635exit: 636 ret void 637} 638 639; Check that every instruction inserted by -passes='require<profile-summary>,function(codegenprepare)' has a debug location. 640; DEBUG: CheckModuleDebugify: PASS 641 642