1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4declare void @llvm.assume(i1) 5declare void @use(i16) 6define i1 @icmp_trunc_x_trunc_y(i32 %x, i32 %y) { 7; CHECK-LABEL: @icmp_trunc_x_trunc_y( 8; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 9; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 10; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 11; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 12; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], [[Y]] 13; CHECK-NEXT: ret i1 [[R]] 14; 15 %x_lb_only = icmp ult i32 %x, 65536 16 %y_lb_only = icmp ult i32 %y, 65536 17 call void @llvm.assume(i1 %x_lb_only) 18 call void @llvm.assume(i1 %y_lb_only) 19 %x16 = trunc i32 %x to i16 20 %y16 = trunc i32 %y to i16 21 %r = icmp eq i16 %x16, %y16 22 ret i1 %r 23} 24 25define i1 @icmp_trunc_x_trunc_y_fail_from_illegal1(i256 %x, i256 %y) { 26; CHECK-LABEL: @icmp_trunc_x_trunc_y_fail_from_illegal1( 27; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i256 [[X:%.*]], 65536 28; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i256 [[Y:%.*]], 65536 29; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 30; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 31; CHECK-NEXT: [[X16:%.*]] = trunc nuw i256 [[X]] to i16 32; CHECK-NEXT: [[Y16:%.*]] = trunc nuw i256 [[Y]] to i16 33; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[X16]], [[Y16]] 34; CHECK-NEXT: ret i1 [[R]] 35; 36 %x_lb_only = icmp ult i256 %x, 65536 37 %y_lb_only = icmp ult i256 %y, 65536 38 call void @llvm.assume(i1 %x_lb_only) 39 call void @llvm.assume(i1 %y_lb_only) 40 %x16 = trunc i256 %x to i16 41 %y16 = trunc i256 %y to i16 42 %r = icmp eq i16 %x16, %y16 43 ret i1 %r 44} 45 46define i1 @icmp_trunc_x_trunc_y_illegal_trunc_to_legal_anyways(i123 %x, i32 %y) { 47; CHECK-LABEL: @icmp_trunc_x_trunc_y_illegal_trunc_to_legal_anyways( 48; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i123 [[X:%.*]], 65536 49; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 50; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 51; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 52; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw nsw i123 [[X]] to i32 53; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[Y]], [[TMP1]] 54; CHECK-NEXT: ret i1 [[R]] 55; 56 %x_lb_only = icmp ult i123 %x, 65536 57 %y_lb_only = icmp ult i32 %y, 65536 58 call void @llvm.assume(i1 %x_lb_only) 59 call void @llvm.assume(i1 %y_lb_only) 60 %x16 = trunc i123 %x to i16 61 %y16 = trunc i32 %y to i16 62 %r = icmp eq i16 %x16, %y16 63 ret i1 %r 64} 65 66define i1 @icmp_trunc_x_trunc_y_2_illegal_anyways(i33 %x, i63 %y) { 67; CHECK-LABEL: @icmp_trunc_x_trunc_y_2_illegal_anyways( 68; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i33 [[X:%.*]], 512 69; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i63 [[Y:%.*]], 512 70; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 71; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 72; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i33 [[X]] to i63 73; CHECK-NEXT: [[R:%.*]] = icmp samesign ult i63 [[Y]], [[TMP1]] 74; CHECK-NEXT: ret i1 [[R]] 75; 76 %x_lb_only = icmp ult i33 %x, 512 77 %y_lb_only = icmp ult i63 %y, 512 78 call void @llvm.assume(i1 %x_lb_only) 79 call void @llvm.assume(i1 %y_lb_only) 80 %x16 = trunc i33 %x to i9 81 %y16 = trunc i63 %y to i9 82 %r = icmp ult i9 %y16, %x16 83 ret i1 %r 84} 85 86define i1 @icmp_trunc_x_trunc_y_3(i64 %x, i32 %y) { 87; CHECK-LABEL: @icmp_trunc_x_trunc_y_3( 88; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i64 [[X:%.*]], 123 89; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 256 90; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 91; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 92; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw nsw i64 [[X]] to i32 93; CHECK-NEXT: [[R:%.*]] = icmp samesign ule i32 [[Y]], [[TMP1]] 94; CHECK-NEXT: ret i1 [[R]] 95; 96 %x_lb_only = icmp ult i64 %x, 123 97 %y_lb_only = icmp ult i32 %y, 256 98 call void @llvm.assume(i1 %x_lb_only) 99 call void @llvm.assume(i1 %y_lb_only) 100 %xi8 = trunc i64 %x to i8 101 %yi8 = trunc i32 %y to i8 102 %r = icmp ule i8 %yi8, %xi8 103 ret i1 %r 104} 105 106define i1 @icmp_trunc_x_trunc_y_fail_maybe_dirty_upper(i32 %x, i32 %y) { 107; CHECK-LABEL: @icmp_trunc_x_trunc_y_fail_maybe_dirty_upper( 108; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 109; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65537 110; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 111; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 112; CHECK-NEXT: [[X16:%.*]] = trunc nuw i32 [[X]] to i16 113; CHECK-NEXT: [[Y16:%.*]] = trunc i32 [[Y]] to i16 114; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[X16]], [[Y16]] 115; CHECK-NEXT: ret i1 [[R]] 116; 117 %x_lb_only = icmp ult i32 %x, 65536 118 %y_lb_only = icmp ult i32 %y, 65537 119 call void @llvm.assume(i1 %x_lb_only) 120 call void @llvm.assume(i1 %y_lb_only) 121 %x16 = trunc i32 %x to i16 122 %y16 = trunc i32 %y to i16 123 %r = icmp ne i16 %x16, %y16 124 ret i1 %r 125} 126 127define i1 @icmp_trunc_x_trunc_y_fail_maybe_dirty_upper_2(i32 %x, i32 %y) { 128; CHECK-LABEL: @icmp_trunc_x_trunc_y_fail_maybe_dirty_upper_2( 129; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp slt i32 [[X:%.*]], 65536 130; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 131; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 132; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 133; CHECK-NEXT: [[X16:%.*]] = trunc i32 [[X]] to i16 134; CHECK-NEXT: [[Y16:%.*]] = trunc nuw i32 [[Y]] to i16 135; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[X16]], [[Y16]] 136; CHECK-NEXT: ret i1 [[R]] 137; 138 %x_lb_only = icmp slt i32 %x, 65536 139 %y_lb_only = icmp ult i32 %y, 65536 140 call void @llvm.assume(i1 %x_lb_only) 141 call void @llvm.assume(i1 %y_lb_only) 142 %x16 = trunc i32 %x to i16 143 %y16 = trunc i32 %y to i16 144 %r = icmp ne i16 %x16, %y16 145 ret i1 %r 146} 147 148define i1 @icmp_trunc_x_trunc_y_swap0(i33 %x, i32 %y) { 149; CHECK-LABEL: @icmp_trunc_x_trunc_y_swap0( 150; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i33 [[X:%.*]], 65536 151; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 152; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 153; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 154; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw nsw i33 [[X]] to i32 155; CHECK-NEXT: [[R:%.*]] = icmp samesign uge i32 [[Y]], [[TMP1]] 156; CHECK-NEXT: ret i1 [[R]] 157; 158 %x_lb_only = icmp ult i33 %x, 65536 159 %y_lb_only = icmp ult i32 %y, 65536 160 call void @llvm.assume(i1 %x_lb_only) 161 call void @llvm.assume(i1 %y_lb_only) 162 %x16 = trunc i33 %x to i16 163 %y16 = trunc i32 %y to i16 164 %r = icmp ule i16 %x16, %y16 165 ret i1 %r 166} 167 168define i1 @icmp_trunc_x_trunc_y_swap1(i33 %x, i32 %y) { 169; CHECK-LABEL: @icmp_trunc_x_trunc_y_swap1( 170; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i33 [[X:%.*]], 65536 171; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 172; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 173; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 174; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw nsw i33 [[X]] to i32 175; CHECK-NEXT: [[R:%.*]] = icmp samesign ule i32 [[Y]], [[TMP1]] 176; CHECK-NEXT: ret i1 [[R]] 177; 178 %x_lb_only = icmp ult i33 %x, 65536 179 %y_lb_only = icmp ult i32 %y, 65536 180 call void @llvm.assume(i1 %x_lb_only) 181 call void @llvm.assume(i1 %y_lb_only) 182 %x16 = trunc i33 %x to i16 183 %y16 = trunc i32 %y to i16 184 %r = icmp ule i16 %y16, %x16 185 ret i1 %r 186} 187 188define i1 @icmp_trunc_x_zext_y(i32 %x, i8 %y) { 189; CHECK-LABEL: @icmp_trunc_x_zext_y( 190; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 191; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 192; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 193; CHECK-NEXT: [[R:%.*]] = icmp samesign ugt i32 [[X]], [[TMP1]] 194; CHECK-NEXT: ret i1 [[R]] 195; 196 %x_lb_only = icmp ult i32 %x, 65536 197 call void @llvm.assume(i1 %x_lb_only) 198 %x16 = trunc i32 %x to i16 199 %y16 = zext i8 %y to i16 200 %r = icmp ugt i16 %x16, %y16 201 ret i1 %r 202} 203 204define i1 @icmp_trunc_x_zext_y_2(i32 %x, i8 %y) { 205; CHECK-LABEL: @icmp_trunc_x_zext_y_2( 206; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 207; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 208; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 209; CHECK-NEXT: [[R:%.*]] = icmp samesign ule i32 [[X]], [[TMP1]] 210; CHECK-NEXT: ret i1 [[R]] 211; 212 %x_lb_only = icmp ult i32 %x, 65536 213 call void @llvm.assume(i1 %x_lb_only) 214 %x16 = trunc i32 %x to i16 215 %y16 = zext i8 %y to i16 216 %r = icmp uge i16 %y16, %x16 217 ret i1 %r 218} 219 220define i1 @icmp_trunc_x_zext_y_3(i6 %x, i32 %y) { 221; CHECK-LABEL: @icmp_trunc_x_zext_y_3( 222; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 223; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 224; CHECK-NEXT: [[TMP1:%.*]] = zext i6 [[X:%.*]] to i32 225; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[Y]], [[TMP1]] 226; CHECK-NEXT: ret i1 [[R]] 227; 228 %y_lb_only = icmp ult i32 %y, 65536 229 call void @llvm.assume(i1 %y_lb_only) 230 %x16 = zext i6 %x to i16 231 %y16 = trunc i32 %y to i16 232 %r = icmp ne i16 %y16, %x16 233 ret i1 %r 234} 235 236define i1 @icmp_trunc_x_zext_y_3_fail_illegal(i6 %x, i45 %y) { 237; CHECK-LABEL: @icmp_trunc_x_zext_y_3_fail_illegal( 238; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i45 [[Y:%.*]], 65536 239; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) 240; CHECK-NEXT: [[X16:%.*]] = zext i6 [[X:%.*]] to i16 241; CHECK-NEXT: [[Y16:%.*]] = trunc nuw i45 [[Y]] to i16 242; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[Y16]], [[X16]] 243; CHECK-NEXT: ret i1 [[R]] 244; 245 %y_lb_only = icmp ult i45 %y, 65536 246 call void @llvm.assume(i1 %y_lb_only) 247 %x16 = zext i6 %x to i16 248 %y16 = trunc i45 %y to i16 249 %r = icmp ne i16 %y16, %x16 250 ret i1 %r 251} 252 253define i1 @icmp_trunc_x_zext_y_fail_multiuse(i32 %x, i8 %y) { 254; CHECK-LABEL: @icmp_trunc_x_zext_y_fail_multiuse( 255; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 256; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) 257; CHECK-NEXT: [[X16:%.*]] = trunc nuw i32 [[X]] to i16 258; CHECK-NEXT: [[Y16:%.*]] = zext i8 [[Y:%.*]] to i16 259; CHECK-NEXT: call void @use(i16 [[Y16]]) 260; CHECK-NEXT: [[R:%.*]] = icmp ule i16 [[X16]], [[Y16]] 261; CHECK-NEXT: ret i1 [[R]] 262; 263 %x_lb_only = icmp ult i32 %x, 65536 264 call void @llvm.assume(i1 %x_lb_only) 265 %x16 = trunc i32 %x to i16 266 %y16 = zext i8 %y to i16 267 call void @use(i16 %y16) 268 %r = icmp ule i16 %x16, %y16 269 ret i1 %r 270} 271 272define i1 @trunc_unsigned_nuw(i16 %x, i16 %y) { 273; CHECK-LABEL: @trunc_unsigned_nuw( 274; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[X:%.*]], [[Y:%.*]] 275; CHECK-NEXT: ret i1 [[C]] 276; 277 %xt = trunc nuw i16 %x to i8 278 %yt = trunc nuw i16 %y to i8 279 %c = icmp ult i8 %xt, %yt 280 ret i1 %c 281} 282 283define i1 @trunc_unsigned_nsw(i16 %x, i16 %y) { 284; CHECK-LABEL: @trunc_unsigned_nsw( 285; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[X:%.*]], [[Y:%.*]] 286; CHECK-NEXT: ret i1 [[C]] 287; 288 %xt = trunc nsw i16 %x to i8 289 %yt = trunc nsw i16 %y to i8 290 %c = icmp ult i8 %xt, %yt 291 ret i1 %c 292} 293 294define i1 @trunc_unsigned_both(i16 %x, i16 %y) { 295; CHECK-LABEL: @trunc_unsigned_both( 296; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[X:%.*]], [[Y:%.*]] 297; CHECK-NEXT: ret i1 [[C]] 298; 299 %xt = trunc nuw nsw i16 %x to i8 300 %yt = trunc nuw nsw i16 %y to i8 301 %c = icmp ult i8 %xt, %yt 302 ret i1 %c 303} 304 305define i1 @trunc_unsigned_either(i16 %x, i16 %y) { 306; CHECK-LABEL: @trunc_unsigned_either( 307; CHECK-NEXT: [[XT:%.*]] = trunc nuw i16 [[X:%.*]] to i8 308; CHECK-NEXT: [[YT:%.*]] = trunc nsw i16 [[Y:%.*]] to i8 309; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[XT]], [[YT]] 310; CHECK-NEXT: ret i1 [[C]] 311; 312 %xt = trunc nuw i16 %x to i8 313 %yt = trunc nsw i16 %y to i8 314 %c = icmp ult i8 %xt, %yt 315 ret i1 %c 316} 317 318define i1 @trunc_signed_nuw(i16 %x, i16 %y) { 319; CHECK-LABEL: @trunc_signed_nuw( 320; CHECK-NEXT: [[XT:%.*]] = trunc nuw i16 [[X:%.*]] to i8 321; CHECK-NEXT: [[YT:%.*]] = trunc nuw i16 [[Y:%.*]] to i8 322; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[XT]], [[YT]] 323; CHECK-NEXT: ret i1 [[C]] 324; 325 %xt = trunc nuw i16 %x to i8 326 %yt = trunc nuw i16 %y to i8 327 %c = icmp slt i8 %xt, %yt 328 ret i1 %c 329} 330 331define i1 @trunc_signed_nsw(i16 %x, i16 %y) { 332; CHECK-LABEL: @trunc_signed_nsw( 333; CHECK-NEXT: [[C:%.*]] = icmp slt i16 [[X:%.*]], [[Y:%.*]] 334; CHECK-NEXT: ret i1 [[C]] 335; 336 %xt = trunc nsw i16 %x to i8 337 %yt = trunc nsw i16 %y to i8 338 %c = icmp slt i8 %xt, %yt 339 ret i1 %c 340} 341 342define i1 @trunc_signed_both(i16 %x, i16 %y) { 343; CHECK-LABEL: @trunc_signed_both( 344; CHECK-NEXT: [[C:%.*]] = icmp slt i16 [[X:%.*]], [[Y:%.*]] 345; CHECK-NEXT: ret i1 [[C]] 346; 347 %xt = trunc nuw nsw i16 %x to i8 348 %yt = trunc nuw nsw i16 %y to i8 349 %c = icmp slt i8 %xt, %yt 350 ret i1 %c 351} 352 353define i1 @trunc_signed_either(i16 %x, i16 %y) { 354; CHECK-LABEL: @trunc_signed_either( 355; CHECK-NEXT: [[XT:%.*]] = trunc nuw i16 [[X:%.*]] to i8 356; CHECK-NEXT: [[YT:%.*]] = trunc nsw i16 [[Y:%.*]] to i8 357; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[XT]], [[YT]] 358; CHECK-NEXT: ret i1 [[C]] 359; 360 %xt = trunc nuw i16 %x to i8 361 %yt = trunc nsw i16 %y to i8 362 %c = icmp slt i8 %xt, %yt 363 ret i1 %c 364} 365 366define i1 @trunc_equality_nuw(i16 %x, i16 %y) { 367; CHECK-LABEL: @trunc_equality_nuw( 368; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[X:%.*]], [[Y:%.*]] 369; CHECK-NEXT: ret i1 [[C]] 370; 371 %xt = trunc nuw i16 %x to i8 372 %yt = trunc nuw i16 %y to i8 373 %c = icmp eq i8 %xt, %yt 374 ret i1 %c 375} 376 377define i1 @trunc_equality_nsw(i16 %x, i16 %y) { 378; CHECK-LABEL: @trunc_equality_nsw( 379; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[X:%.*]], [[Y:%.*]] 380; CHECK-NEXT: ret i1 [[C]] 381; 382 %xt = trunc nsw i16 %x to i8 383 %yt = trunc nsw i16 %y to i8 384 %c = icmp eq i8 %xt, %yt 385 ret i1 %c 386} 387 388define i1 @trunc_equality_both(i16 %x, i16 %y) { 389; CHECK-LABEL: @trunc_equality_both( 390; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[X:%.*]], [[Y:%.*]] 391; CHECK-NEXT: ret i1 [[C]] 392; 393 %xt = trunc nuw nsw i16 %x to i8 394 %yt = trunc nuw nsw i16 %y to i8 395 %c = icmp eq i8 %xt, %yt 396 ret i1 %c 397} 398 399define i1 @trunc_equality_either(i16 %x, i16 %y) { 400; CHECK-LABEL: @trunc_equality_either( 401; CHECK-NEXT: [[XT:%.*]] = trunc nuw i16 [[X:%.*]] to i8 402; CHECK-NEXT: [[YT:%.*]] = trunc nsw i16 [[Y:%.*]] to i8 403; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[XT]], [[YT]] 404; CHECK-NEXT: ret i1 [[C]] 405; 406 %xt = trunc nuw i16 %x to i8 407 %yt = trunc nsw i16 %y to i8 408 %c = icmp eq i8 %xt, %yt 409 ret i1 %c 410} 411 412define i1 @trunc_unsigned_nuw_zext(i32 %x, i8 %y) { 413; CHECK-LABEL: @trunc_unsigned_nuw_zext( 414; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 415; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[TMP1]] 416; CHECK-NEXT: ret i1 [[C]] 417; 418 %xt = trunc nuw i32 %x to i16 419 %ye = zext i8 %y to i16 420 %c = icmp ult i16 %xt, %ye 421 ret i1 %c 422} 423 424define i1 @trunc_unsigned_nuw_sext(i32 %x, i8 %y) { 425; CHECK-LABEL: @trunc_unsigned_nuw_sext( 426; CHECK-NEXT: [[XT:%.*]] = trunc nuw i32 [[X:%.*]] to i16 427; CHECK-NEXT: [[YE:%.*]] = sext i8 [[Y:%.*]] to i16 428; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[XT]], [[YE]] 429; CHECK-NEXT: ret i1 [[C]] 430; 431 %xt = trunc nuw i32 %x to i16 432 %ye = sext i8 %y to i16 433 %c = icmp ult i16 %xt, %ye 434 ret i1 %c 435} 436 437define i1 @trunc_unsigned_nsw_zext(i32 %x, i8 %y) { 438; CHECK-LABEL: @trunc_unsigned_nsw_zext( 439; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 440; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[TMP1]] 441; CHECK-NEXT: ret i1 [[C]] 442; 443 %xt = trunc nsw i32 %x to i16 444 %ye = zext i8 %y to i16 445 %c = icmp ult i16 %xt, %ye 446 ret i1 %c 447} 448 449define i1 @trunc_unsigned_nsw_sext(i32 %x, i8 %y) { 450; CHECK-LABEL: @trunc_unsigned_nsw_sext( 451; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i32 452; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[TMP1]] 453; CHECK-NEXT: ret i1 [[C]] 454; 455 %xt = trunc nsw i32 %x to i16 456 %ye = sext i8 %y to i16 457 %c = icmp ult i16 %xt, %ye 458 ret i1 %c 459} 460 461define i1 @trunc_signed_nsw_sext(i32 %x, i8 %y) { 462; CHECK-LABEL: @trunc_signed_nsw_sext( 463; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i32 464; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], [[TMP1]] 465; CHECK-NEXT: ret i1 [[C]] 466; 467 %xt = trunc nsw i32 %x to i16 468 %ye = sext i8 %y to i16 469 %c = icmp slt i16 %xt, %ye 470 ret i1 %c 471} 472 473define i1 @trunc_signed_nsw_zext(i32 %x, i8 %y) { 474; CHECK-LABEL: @trunc_signed_nsw_zext( 475; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 476; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], [[TMP1]] 477; CHECK-NEXT: ret i1 [[C]] 478; 479 %xt = trunc nsw i32 %x to i16 480 %ye = zext i8 %y to i16 481 %c = icmp slt i16 %xt, %ye 482 ret i1 %c 483} 484 485define i1 @trunc_signed_nuw_sext(i32 %x, i8 %y) { 486; CHECK-LABEL: @trunc_signed_nuw_sext( 487; CHECK-NEXT: [[XT:%.*]] = trunc nuw i32 [[X:%.*]] to i16 488; CHECK-NEXT: [[YE:%.*]] = sext i8 [[Y:%.*]] to i16 489; CHECK-NEXT: [[C:%.*]] = icmp slt i16 [[XT]], [[YE]] 490; CHECK-NEXT: ret i1 [[C]] 491; 492 %xt = trunc nuw i32 %x to i16 493 %ye = sext i8 %y to i16 494 %c = icmp slt i16 %xt, %ye 495 ret i1 %c 496} 497 498define i1 @trunc_signed_nuw_zext(i32 %x, i8 %y) { 499; CHECK-LABEL: @trunc_signed_nuw_zext( 500; CHECK-NEXT: [[XT:%.*]] = trunc nuw i32 [[X:%.*]] to i16 501; CHECK-NEXT: [[YE:%.*]] = zext i8 [[Y:%.*]] to i16 502; CHECK-NEXT: [[C:%.*]] = icmp slt i16 [[XT]], [[YE]] 503; CHECK-NEXT: ret i1 [[C]] 504; 505 %xt = trunc nuw i32 %x to i16 506 %ye = zext i8 %y to i16 507 %c = icmp slt i16 %xt, %ye 508 ret i1 %c 509} 510 511define i1 @trunc_equality_nuw_zext(i32 %x, i8 %y) { 512; CHECK-LABEL: @trunc_equality_nuw_zext( 513; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 514; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[TMP1]] 515; CHECK-NEXT: ret i1 [[C]] 516; 517 %xt = trunc nuw i32 %x to i16 518 %ye = zext i8 %y to i16 519 %c = icmp ne i16 %xt, %ye 520 ret i1 %c 521} 522 523define i1 @trunc_equality_nuw_sext(i32 %x, i8 %y) { 524; CHECK-LABEL: @trunc_equality_nuw_sext( 525; CHECK-NEXT: [[XT:%.*]] = trunc nuw i32 [[X:%.*]] to i16 526; CHECK-NEXT: [[YE:%.*]] = sext i8 [[Y:%.*]] to i16 527; CHECK-NEXT: [[C:%.*]] = icmp ne i16 [[XT]], [[YE]] 528; CHECK-NEXT: ret i1 [[C]] 529; 530 %xt = trunc nuw i32 %x to i16 531 %ye = sext i8 %y to i16 532 %c = icmp ne i16 %xt, %ye 533 ret i1 %c 534} 535 536define i1 @trunc_equality_nsw_zext(i32 %x, i8 %y) { 537; CHECK-LABEL: @trunc_equality_nsw_zext( 538; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i32 539; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[TMP1]] 540; CHECK-NEXT: ret i1 [[C]] 541; 542 %xt = trunc nsw i32 %x to i16 543 %ye = zext i8 %y to i16 544 %c = icmp ne i16 %xt, %ye 545 ret i1 %c 546} 547 548define i1 @trunc_equality_nsw_sext(i32 %x, i8 %y) { 549; CHECK-LABEL: @trunc_equality_nsw_sext( 550; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i32 551; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[TMP1]] 552; CHECK-NEXT: ret i1 [[C]] 553; 554 %xt = trunc nsw i32 %x to i16 555 %ye = sext i8 %y to i16 556 %c = icmp ne i16 %xt, %ye 557 ret i1 %c 558} 559 560define i1 @trunc_equality_both_sext(i32 %x, i8 %y) { 561; CHECK-LABEL: @trunc_equality_both_sext( 562; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i32 563; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[TMP1]] 564; CHECK-NEXT: ret i1 [[C]] 565; 566 %xt = trunc nuw nsw i32 %x to i16 567 %ye = sext i8 %y to i16 568 %c = icmp ne i16 %xt, %ye 569 ret i1 %c 570} 571 572define i1 @test_eq1(i32 %x, i16 %y) { 573; CHECK-LABEL: @test_eq1( 574; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[Y:%.*]] to i32 575; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X:%.*]], [[TMP1]] 576; CHECK-NEXT: ret i1 [[COND]] 577; 578 %conv1 = trunc nsw i32 %x to i8 579 %conv2 = trunc nsw i16 %y to i8 580 %cond = icmp eq i8 %conv1, %conv2 581 ret i1 %cond 582} 583 584; FIXME: It is weird that we generate truncs for test_eq2, but not for test_eq1. 585 586define i1 @test_eq2(i32 %x, i16 %y) { 587; CHECK-LABEL: @test_eq2( 588; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 589; CHECK-NEXT: [[COND:%.*]] = icmp eq i16 [[Y:%.*]], [[TMP1]] 590; CHECK-NEXT: ret i1 [[COND]] 591; 592 %conv1 = trunc nsw i32 %x to i8 593 %conv2 = trunc nsw i16 %y to i8 594 %cond = icmp eq i8 %conv2, %conv1 595 ret i1 %cond 596} 597 598define i1 @test_ult(i32 %x, i16 %y) { 599; CHECK-LABEL: @test_ult( 600; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[Y:%.*]] to i32 601; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X:%.*]], [[TMP1]] 602; CHECK-NEXT: ret i1 [[COND]] 603; 604 %conv1 = trunc nsw i32 %x to i8 605 %conv2 = trunc nsw i16 %y to i8 606 %cond = icmp ult i8 %conv1, %conv2 607 ret i1 %cond 608} 609 610define i1 @test_slt(i32 %x, i16 %y) { 611; CHECK-LABEL: @test_slt( 612; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[Y:%.*]] to i32 613; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X:%.*]], [[TMP1]] 614; CHECK-NEXT: ret i1 [[COND]] 615; 616 %conv1 = trunc nsw i32 %x to i8 617 %conv2 = trunc nsw i16 %y to i8 618 %cond = icmp slt i8 %conv1, %conv2 619 ret i1 %cond 620} 621 622define i1 @test_ult_nuw(i32 %x, i16 %y) { 623; CHECK-LABEL: @test_ult_nuw( 624; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[Y:%.*]] to i32 625; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X:%.*]], [[TMP1]] 626; CHECK-NEXT: ret i1 [[COND]] 627; 628 %conv1 = trunc nuw nsw i32 %x to i8 629 %conv2 = trunc nuw nsw i16 %y to i8 630 %cond = icmp ult i8 %conv1, %conv2 631 ret i1 %cond 632} 633 634define i1 @test_slt_nuw(i32 %x, i16 %y) { 635; CHECK-LABEL: @test_slt_nuw( 636; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[Y:%.*]] to i32 637; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X:%.*]], [[TMP1]] 638; CHECK-NEXT: ret i1 [[COND]] 639; 640 %conv1 = trunc nuw nsw i32 %x to i8 641 %conv2 = trunc nuw nsw i16 %y to i8 642 %cond = icmp slt i8 %conv1, %conv2 643 ret i1 %cond 644} 645 646@foo = external global i8 647@bar = external global i8 648 649define i1 @constexpr_trunc() { 650; CHECK-LABEL: @constexpr_trunc( 651; CHECK-NEXT: [[CMP5:%.*]] = icmp ne i16 trunc (i64 sub (i64 sub (i64 ptrtoint (ptr @bar to i64), i64 ptrtoint (ptr @foo to i64)), i64 8) to i16), trunc (i64 sub (i64 sub (i64 0, i64 ptrtoint (ptr @foo to i64)), i64 8) to i16) 652; CHECK-NEXT: ret i1 [[CMP5]] 653; 654 %conv = zext i16 trunc (i64 sub (i64 sub nuw nsw (i64 ptrtoint (ptr @bar to i64), i64 ptrtoint (ptr @foo to i64)), i64 8) to i16) to i32 655 %conv1 = zext i16 trunc (i64 sub (i64 sub nuw nsw (i64 0, i64 ptrtoint (ptr @foo to i64)), i64 8) to i16) to i32 656 %cmp5 = icmp ne i32 %conv, %conv1 657 ret i1 %cmp5 658} 659