1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instsimplify < %s -S | FileCheck %s 3 4declare void @llvm.assume(i1) 5declare i8 @llvm.abs.i8(i8, i1) 6declare i8 @llvm.bitreverse.i8(i8) 7declare i16 @llvm.bswap.i16(i16) 8declare i8 @llvm.ctpop.i8(i8) 9declare <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8>, <2 x i8>) 10declare i8 @llvm.uadd.sat.i8(i8, i8) 11declare i8 @llvm.fshr.i8(i8, i8, i8) 12declare i8 @llvm.fshl.i8(i8, i8, i8) 13declare i8 @llvm.ctlz.i8(i8, i1) 14declare i8 @llvm.cttz.i8(i8, i1) 15declare i8 @llvm.sadd.sat.i8(i8, i8) 16declare i8 @llvm.smax.i8(i8, i8) 17declare i8 @llvm.smin.i8(i8, i8) 18declare i8 @llvm.sshl.sat.i8(i8, i8) 19declare i8 @llvm.ssub.sat.i8(i8, i8) 20declare i8 @llvm.umax.i8(i8, i8) 21declare i8 @llvm.umin.i8(i8, i8) 22declare i8 @llvm.ushl.sat.i8(i8, i8) 23declare i8 @llvm.usub.sat.i8(i8, i8) 24declare float @llvm.maximum.f32(float, float) 25 26;; Throughout use: X > Y || Y == 0 which folds to X > Y iff X known 27;; non-zero. Do this because many of the expressions already have 28;; hardcoded cases for folding Foo(X) == 0 -> X == 0 and we want to 29;; test explicitly that `isKnownNonZero` works. 30 31define i1 @check_neg(i8 %x, i8 %y) { 32; CHECK-LABEL: @check_neg( 33; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0 34; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 35; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[X]] 36; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] 37; CHECK-NEXT: ret i1 [[CMP0]] 38; 39 %ne = icmp ne i8 %x, 0 40 call void @llvm.assume(i1 %ne) 41 %z = sub i8 0, %x 42 %cmp0 = icmp ugt i8 %z, %y 43 %cmp1 = icmp eq i8 %y, 0 44 %r = or i1 %cmp0, %cmp1 45 ret i1 %r 46} 47 48define i1 @check_abs(i8 %x, i8 %y) { 49; CHECK-LABEL: @check_abs( 50; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0 51; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]] 52; CHECK: true: 53; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 54; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] 55; CHECK-NEXT: ret i1 [[CMP0]] 56; CHECK: false: 57; CHECK-NEXT: ret i1 [[NE]] 58; 59 %ne = icmp ne i8 %x, 0 60 br i1 %ne, label %true, label %false 61true: 62 %z = call i8 @llvm.abs.i8(i8 %x, i1 true) 63 %cmp0 = icmp ugt i8 %z, %y 64 %cmp1 = icmp eq i8 %y, 0 65 %r = or i1 %cmp0, %cmp1 66 ret i1 %r 67false: 68 ret i1 %ne 69} 70 71define i1 @check_abs_failish(i8 %x, i8 %y) { 72; CHECK-LABEL: @check_abs_failish( 73; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0 74; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]] 75; CHECK: false: 76; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 77; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] 78; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0 79; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] 80; CHECK-NEXT: ret i1 [[R]] 81; CHECK: true: 82; CHECK-NEXT: ret i1 [[NE]] 83; 84 %ne = icmp ne i8 %x, 0 85 br i1 %ne, label %true, label %false 86false: 87 %z = call i8 @llvm.abs.i8(i8 %x, i1 true) 88 %cmp0 = icmp ugt i8 %z, %y 89 %cmp1 = icmp eq i8 %y, 0 90 %r = or i1 %cmp0, %cmp1 91 ret i1 %r 92true: 93 ret i1 %ne 94} 95 96define i1 @check_bitreverse(i8 %x, i8 %y) { 97; CHECK-LABEL: @check_bitreverse( 98; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0 99; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 100; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[X]]) 101; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] 102; CHECK-NEXT: ret i1 [[CMP0]] 103; 104 %ne = icmp ne i8 %x, 0 105 call void @llvm.assume(i1 %ne) 106 %z = call i8 @llvm.bitreverse.i8(i8 %x) 107 %cmp0 = icmp ugt i8 %z, %y 108 %cmp1 = icmp eq i8 %y, 0 109 %r = or i1 %cmp0, %cmp1 110 ret i1 %r 111} 112 113define i1 @check_bswap(i16 %x, i16 %y) { 114; CHECK-LABEL: @check_bswap( 115; CHECK-NEXT: [[NE:%.*]] = icmp ne i16 [[X:%.*]], 0 116; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 117; CHECK-NEXT: [[Z:%.*]] = call i16 @llvm.bswap.i16(i16 [[X]]) 118; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i16 [[Z]], [[Y:%.*]] 119; CHECK-NEXT: ret i1 [[CMP0]] 120; 121 %ne = icmp ne i16 %x, 0 122 call void @llvm.assume(i1 %ne) 123 %z = call i16 @llvm.bswap.i16(i16 %x) 124 %cmp0 = icmp ugt i16 %z, %y 125 %cmp1 = icmp eq i16 %y, 0 126 %r = or i1 %cmp0, %cmp1 127 ret i1 %r 128} 129 130define i1 @check_ctpop(i8 %x, i8 %y) { 131; CHECK-LABEL: @check_ctpop( 132; CHECK-NEXT: [[NE:%.*]] = icmp eq i8 [[X:%.*]], 0 133; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]] 134; CHECK: true: 135; CHECK-NEXT: ret i1 [[NE]] 136; CHECK: false: 137; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X]]) 138; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] 139; CHECK-NEXT: ret i1 [[CMP0]] 140; 141 %ne = icmp eq i8 %x, 0 142 br i1 %ne, label %true, label %false 143true: 144 ret i1 %ne 145false: 146 %z = call i8 @llvm.ctpop.i8(i8 %x) 147 %cmp0 = icmp ugt i8 %z, %y 148 %cmp1 = icmp eq i8 %y, 0 149 %r = or i1 %cmp0, %cmp1 150 ret i1 %r 151} 152 153define i1 @check_add_sat(i8 %x, i8 %y, i8 %w) { 154; CHECK-LABEL: @check_add_sat( 155; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0 156; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 157; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X]], i8 [[Y:%.*]]) 158; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[W:%.*]] 159; CHECK-NEXT: ret i1 [[CMP0]] 160; 161 %ne = icmp ne i8 %x, 0 162 call void @llvm.assume(i1 %ne) 163 %z = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y) 164 %cmp0 = icmp ugt i8 %z, %w 165 %cmp1 = icmp eq i8 %w, 0 166 %r = or i1 %cmp0, %cmp1 167 ret i1 %r 168} 169 170define <2 x i1> @check_add_sat_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %w) { 171; CHECK-LABEL: @check_add_sat_vec( 172; CHECK-NEXT: [[YNZ:%.*]] = or <2 x i8> [[Y:%.*]], <i8 2, i8 1> 173; CHECK-NEXT: [[Z:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[YNZ]]) 174; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt <2 x i8> [[Z]], [[W:%.*]] 175; CHECK-NEXT: ret <2 x i1> [[CMP0]] 176; 177 %ynz = or <2 x i8> %y, <i8 2, i8 1> 178 %z = call <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8> %x, <2 x i8> %ynz) 179 %cmp0 = icmp ugt <2 x i8> %z, %w 180 %cmp1 = icmp eq <2 x i8> %w, <i8 0, i8 0> 181 %r = or <2 x i1> %cmp0, %cmp1 182 ret <2 x i1> %r 183} 184 185define <2 x i1> @shl_nz_bounded_cnt_vec(<2 x i32> %x, <2 x i32> %y) { 186; CHECK-LABEL: @shl_nz_bounded_cnt_vec( 187; CHECK-NEXT: ret <2 x i1> zeroinitializer 188; 189 %cnt = and <2 x i32> %x, <i32 16, i32 24> 190 %val = or <2 x i32> %y, <i32 131088, i32 16> 191 %shl = shl <2 x i32> %val, %cnt 192 %r = icmp eq <2 x i32> %shl, zeroinitializer 193 ret <2 x i1> %r 194} 195 196define i1 @shl_nz_bounded_cnt(i32 %cnt, i32 %y) { 197; CHECK-LABEL: @shl_nz_bounded_cnt( 198; CHECK-NEXT: [[CNT_ULT4:%.*]] = icmp ult i32 [[CNT:%.*]], 4 199; CHECK-NEXT: call void @llvm.assume(i1 [[CNT_ULT4]]) 200; CHECK-NEXT: ret i1 false 201; 202 %cnt_ult4 = icmp ult i32 %cnt, 4 203 call void @llvm.assume(i1 %cnt_ult4) 204 %val = or i32 %y, 131072 205 %shl = shl i32 %val, %cnt 206 %r = icmp eq i32 %shl, 0 207 ret i1 %r 208} 209 210define <2 x i1> @shl_nz_bounded_cnt_vec_todo_no_common_bit(<2 x i32> %x, <2 x i32> %y) { 211; CHECK-LABEL: @shl_nz_bounded_cnt_vec_todo_no_common_bit( 212; CHECK-NEXT: [[CNT:%.*]] = and <2 x i32> [[X:%.*]], <i32 16, i32 32> 213; CHECK-NEXT: [[VAL:%.*]] = or <2 x i32> [[Y:%.*]], splat (i32 16) 214; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[VAL]], [[CNT]] 215; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer 216; CHECK-NEXT: ret <2 x i1> [[R]] 217; 218 %cnt = and <2 x i32> %x, <i32 16, i32 32> 219 %val = or <2 x i32> %y, <i32 16, i32 16> 220 %shl = shl <2 x i32> %val, %cnt 221 %r = icmp eq <2 x i32> %shl, zeroinitializer 222 ret <2 x i1> %r 223} 224 225define i1 @shl_maybe_zero_bounded_cnt_fail(i32 %x, i32 %y) { 226; CHECK-LABEL: @shl_maybe_zero_bounded_cnt_fail( 227; CHECK-NEXT: [[CNT:%.*]] = and i32 [[X:%.*]], 16 228; CHECK-NEXT: [[VAL:%.*]] = or i32 [[Y:%.*]], 65536 229; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[VAL]], [[CNT]] 230; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SHL]], 0 231; CHECK-NEXT: ret i1 [[R]] 232; 233 %cnt = and i32 %x, 16 234 %val = or i32 %y, 65536 235 %shl = shl i32 %val, %cnt 236 %r = icmp eq i32 %shl, 0 237 ret i1 %r 238} 239 240define i1 @shl_non_zero_nsw(i8 %s, i8 %cnt) { 241; CHECK-LABEL: @shl_non_zero_nsw( 242; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[S:%.*]], 0 243; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]]) 244; CHECK-NEXT: ret i1 false 245; 246 %nz = icmp ne i8 %s, 0 247 call void @llvm.assume(i1 %nz) 248 %v = shl nsw i8 %s, %cnt 249 %r = icmp eq i8 %v, 0 250 ret i1 %r 251} 252 253define i1 @shl_maybe_zero_nsw_fail(i8 %s, i8 %cnt) { 254; CHECK-LABEL: @shl_maybe_zero_nsw_fail( 255; CHECK-NEXT: [[V:%.*]] = shl nsw i8 [[S:%.*]], [[CNT:%.*]] 256; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[V]], 0 257; CHECK-NEXT: ret i1 [[R]] 258; 259 %v = shl nsw i8 %s, %cnt 260 %r = icmp eq i8 %v, 0 261 ret i1 %r 262} 263 264define i1 @shl_out_of_range_is_poison(i32 %v, i32 %c) { 265; CHECK-LABEL: @shl_out_of_range_is_poison( 266; CHECK-NEXT: ret i1 poison 267; 268 %sval = or i32 %v, 32 269 %shl = shl i32 %c, %sval 270 %z = icmp eq i32 %shl, 0 271 ret i1 %z 272} 273 274define i1 @lshr_nz_bounded_cnt(i32 %cnt, i32 %y) { 275; CHECK-LABEL: @lshr_nz_bounded_cnt( 276; CHECK-NEXT: [[CNT_ULT4:%.*]] = icmp ult i32 [[CNT:%.*]], 4 277; CHECK-NEXT: call void @llvm.assume(i1 [[CNT_ULT4]]) 278; CHECK-NEXT: ret i1 false 279; 280 %cnt_ult4 = icmp ult i32 %cnt, 4 281 call void @llvm.assume(i1 %cnt_ult4) 282 %val = or i32 %y, 90 283 %shl = lshr i32 %val, %cnt 284 %r = icmp eq i32 %shl, 0 285 ret i1 %r 286} 287 288define <2 x i1> @ashr_nz_bounded_cnt_vec(<2 x i32> %x, <2 x i32> %y) { 289; CHECK-LABEL: @ashr_nz_bounded_cnt_vec( 290; CHECK-NEXT: ret <2 x i1> zeroinitializer 291; 292 %cnt = and <2 x i32> %x, <i32 16, i32 24> 293 %val = or <2 x i32> %y, <i32 402784272, i32 268697601> 294 %shl = ashr <2 x i32> %val, %cnt 295 %r = icmp eq <2 x i32> %shl, zeroinitializer 296 ret <2 x i1> %r 297} 298 299define i1 @lshr_nz_bounded_cnt_fail(i32 %cnt, i32 %y) { 300; CHECK-LABEL: @lshr_nz_bounded_cnt_fail( 301; CHECK-NEXT: [[CNT_ULT:%.*]] = icmp ult i32 [[CNT:%.*]], 20 302; CHECK-NEXT: call void @llvm.assume(i1 [[CNT_ULT]]) 303; CHECK-NEXT: [[VAL:%.*]] = or i32 [[Y:%.*]], 131072 304; CHECK-NEXT: [[SHL:%.*]] = lshr i32 [[VAL]], [[CNT]] 305; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SHL]], 0 306; CHECK-NEXT: ret i1 [[R]] 307; 308 %cnt_ult = icmp ult i32 %cnt, 20 309 call void @llvm.assume(i1 %cnt_ult) 310 %val = or i32 %y, 131072 311 %shl = lshr i32 %val, %cnt 312 %r = icmp eq i32 %shl, 0 313 ret i1 %r 314} 315 316define <2 x i1> @ashr_nz_bounded_cnt_vec_fail(<2 x i32> %x, <2 x i32> %y) { 317; CHECK-LABEL: @ashr_nz_bounded_cnt_vec_fail( 318; CHECK-NEXT: [[CNT:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 24) 319; CHECK-NEXT: [[VAL:%.*]] = or <2 x i32> [[Y:%.*]], <i32 131088, i32 268697601> 320; CHECK-NEXT: [[SHL:%.*]] = ashr <2 x i32> [[VAL]], [[CNT]] 321; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer 322; CHECK-NEXT: ret <2 x i1> [[R]] 323; 324 %cnt = and <2 x i32> %x, <i32 24, i32 24> 325 %val = or <2 x i32> %y, <i32 131088, i32 268697601> 326 %shl = ashr <2 x i32> %val, %cnt 327 %r = icmp eq <2 x i32> %shl, zeroinitializer 328 ret <2 x i1> %r 329} 330 331define i1 @lshr_nonzero_and_shift_out_zeros(i32 %cnt, i32 %y) { 332; CHECK-LABEL: @lshr_nonzero_and_shift_out_zeros( 333; CHECK-NEXT: [[CNT_ULT:%.*]] = icmp ult i32 [[CNT:%.*]], 4 334; CHECK-NEXT: call void @llvm.assume(i1 [[CNT_ULT]]) 335; CHECK-NEXT: [[VAL:%.*]] = and i32 [[Y:%.*]], -131072 336; CHECK-NEXT: [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0 337; CHECK-NEXT: call void @llvm.assume(i1 [[VAL_NZ]]) 338; CHECK-NEXT: ret i1 false 339; 340 %cnt_ult = icmp ult i32 %cnt, 4 341 call void @llvm.assume(i1 %cnt_ult) 342 %val = and i32 %y, -131072 343 %val_nz = icmp ne i32 %val, 0 344 call void @llvm.assume(i1 %val_nz) 345 %shl = lshr i32 %val, %cnt 346 %r = icmp eq i32 %shl, 0 347 ret i1 %r 348} 349 350define i1 @ashr_nonzero_and_shift_out_zeros(i32 %ccnt, i32 %y) { 351; CHECK-LABEL: @ashr_nonzero_and_shift_out_zeros( 352; CHECK-NEXT: [[VAL:%.*]] = and i32 [[Y:%.*]], -131072 353; CHECK-NEXT: [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0 354; CHECK-NEXT: call void @llvm.assume(i1 [[VAL_NZ]]) 355; CHECK-NEXT: ret i1 false 356; 357 %cnt = and i32 %ccnt, 7 358 %val = and i32 %y, -131072 359 %val_nz = icmp ne i32 %val, 0 360 call void @llvm.assume(i1 %val_nz) 361 %shl = ashr i32 %val, %cnt 362 %r = icmp eq i32 %shl, 0 363 ret i1 %r 364} 365 366define i1 @shl_nonzero_and_shift_out_zeros(i32 %ccnt, i32 %y) { 367; CHECK-LABEL: @shl_nonzero_and_shift_out_zeros( 368; CHECK-NEXT: [[VAL:%.*]] = and i32 [[Y:%.*]], 131071 369; CHECK-NEXT: [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0 370; CHECK-NEXT: call void @llvm.assume(i1 [[VAL_NZ]]) 371; CHECK-NEXT: ret i1 false 372; 373 %cnt = and i32 %ccnt, 6 374 %val = and i32 %y, 131071 375 %val_nz = icmp ne i32 %val, 0 376 call void @llvm.assume(i1 %val_nz) 377 %shl = shl i32 %val, %cnt 378 %r = icmp eq i32 %shl, 0 379 ret i1 %r 380} 381 382define i1 @lshr_nonzero_and_shift_out_zeros_fail(i32 %cnt, i32 %y) { 383; CHECK-LABEL: @lshr_nonzero_and_shift_out_zeros_fail( 384; CHECK-NEXT: [[CNT_ULT:%.*]] = icmp ult i32 [[CNT:%.*]], 19 385; CHECK-NEXT: call void @llvm.assume(i1 [[CNT_ULT]]) 386; CHECK-NEXT: [[VAL:%.*]] = and i32 [[Y:%.*]], -131072 387; CHECK-NEXT: [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0 388; CHECK-NEXT: call void @llvm.assume(i1 [[VAL_NZ]]) 389; CHECK-NEXT: [[SHL:%.*]] = lshr i32 [[VAL]], [[CNT]] 390; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SHL]], 0 391; CHECK-NEXT: ret i1 [[R]] 392; 393 %cnt_ult = icmp ult i32 %cnt, 19 394 call void @llvm.assume(i1 %cnt_ult) 395 %val = and i32 %y, -131072 396 %val_nz = icmp ne i32 %val, 0 397 call void @llvm.assume(i1 %val_nz) 398 %shl = lshr i32 %val, %cnt 399 %r = icmp eq i32 %shl, 0 400 ret i1 %r 401} 402 403define i1 @ashr_nonzero_and_shift_out_zeros_fail(i32 %ccnt, i32 %y) { 404; CHECK-LABEL: @ashr_nonzero_and_shift_out_zeros_fail( 405; CHECK-NEXT: [[CNT:%.*]] = and i32 [[CCNT:%.*]], 18 406; CHECK-NEXT: [[VAL:%.*]] = and i32 [[Y:%.*]], -131072 407; CHECK-NEXT: [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0 408; CHECK-NEXT: call void @llvm.assume(i1 [[VAL_NZ]]) 409; CHECK-NEXT: [[SHL:%.*]] = ashr i32 [[VAL]], [[CNT]] 410; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SHL]], 0 411; CHECK-NEXT: ret i1 [[R]] 412; 413 %cnt = and i32 %ccnt, 18 414 %val = and i32 %y, -131072 415 %val_nz = icmp ne i32 %val, 0 416 call void @llvm.assume(i1 %val_nz) 417 %shl = ashr i32 %val, %cnt 418 %r = icmp eq i32 %shl, 0 419 ret i1 %r 420} 421 422define i1 @shl_nonzero_and_shift_out_zeros_fail(i32 %ccnt, i32 %y) { 423; CHECK-LABEL: @shl_nonzero_and_shift_out_zeros_fail( 424; CHECK-NEXT: [[CNT:%.*]] = and i32 [[CCNT:%.*]], 6 425; CHECK-NEXT: [[VAL:%.*]] = and i32 [[Y:%.*]], 268435455 426; CHECK-NEXT: [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0 427; CHECK-NEXT: call void @llvm.assume(i1 [[VAL_NZ]]) 428; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[VAL]], [[CNT]] 429; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SHL]], 0 430; CHECK-NEXT: ret i1 [[R]] 431; 432 %cnt = and i32 %ccnt, 6 433 %val = and i32 %y, 268435455 434 %val_nz = icmp ne i32 %val, 0 435 call void @llvm.assume(i1 %val_nz) 436 %shl = shl i32 %val, %cnt 437 %r = icmp eq i32 %shl, 0 438 ret i1 %r 439} 440 441define i1 @sub_nonzero_ops_ne(i8 %xx, i8 %yy, i8 %z) { 442; CHECK-LABEL: @sub_nonzero_ops_ne( 443; CHECK-NEXT: ret i1 false 444; 445 %x = and i8 %xx, 191 446 %y = or i8 %yy, 64 447 %s = sub i8 %x, %y 448 %exp = or i8 %z, %s 449 %r = icmp eq i8 %exp, 0 450 ret i1 %r 451} 452 453define i1 @sub_nonzero_ops_ne_fail(i8 %xx, i8 %yy, i8 %z) { 454; CHECK-LABEL: @sub_nonzero_ops_ne_fail( 455; CHECK-NEXT: [[X:%.*]] = and i8 [[XX:%.*]], -64 456; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY:%.*]], 64 457; CHECK-NEXT: [[S:%.*]] = sub i8 [[X]], [[Y]] 458; CHECK-NEXT: [[EXP:%.*]] = or i8 [[Z:%.*]], [[S]] 459; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[EXP]], 0 460; CHECK-NEXT: ret i1 [[R]] 461; 462 %x = and i8 %xx, 192 463 %y = or i8 %yy, 64 464 %s = sub i8 %x, %y 465 %exp = or i8 %z, %s 466 %r = icmp eq i8 %exp, 0 467 ret i1 %r 468} 469 470define i1 @add_nonzero_nuw(i8 %x, i8 %y) { 471; CHECK-LABEL: @add_nonzero_nuw( 472; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[X:%.*]], 0 473; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 474; CHECK-NEXT: ret i1 false 475; 476 %x_nz = icmp ne i8 %x, 0 477 call void @llvm.assume(i1 %x_nz) 478 %a = add nuw i8 %x, %y 479 %r = icmp eq i8 %a, 0 480 ret i1 %r 481} 482 483define i1 @add_nonzero_nsw_fail(i8 %x, i8 %y) { 484; CHECK-LABEL: @add_nonzero_nsw_fail( 485; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[X:%.*]], 0 486; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 487; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[X]], [[Y:%.*]] 488; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[A]], 0 489; CHECK-NEXT: ret i1 [[R]] 490; 491 %x_nz = icmp ne i8 %x, 0 492 call void @llvm.assume(i1 %x_nz) 493 %a = add nsw i8 %x, %y 494 %r = icmp eq i8 %a, 0 495 ret i1 %r 496} 497 498define i1 @udiv_y_le_x(i8 %xx, i8 %yy, i8 %z) { 499; CHECK-LABEL: @udiv_y_le_x( 500; CHECK-NEXT: ret i1 false 501; 502 %x = or i8 %xx, 7 503 %y = and i8 %yy, 7 504 %d = udiv i8 %x, %y 505 %o = or i8 %d, %z 506 %r = icmp eq i8 %o, 0 507 ret i1 %r 508} 509 510define i1 @udiv_y_le_x_fail(i8 %xx, i8 %yy, i8 %z) { 511; CHECK-LABEL: @udiv_y_le_x_fail( 512; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 6 513; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], 7 514; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X]], [[Y]] 515; CHECK-NEXT: [[O:%.*]] = or i8 [[D]], [[Z:%.*]] 516; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[O]], 0 517; CHECK-NEXT: ret i1 [[R]] 518; 519 %x = or i8 %xx, 6 520 %y = and i8 %yy, 7 521 %d = udiv i8 %x, %y 522 %o = or i8 %d, %z 523 %r = icmp eq i8 %o, 0 524 ret i1 %r 525} 526 527define i1 @fshr_non_zero(i8 %x, i8 %y, i8 %z) { 528; CHECK-LABEL: @fshr_non_zero( 529; CHECK-NEXT: [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0 530; CHECK-NEXT: call void @llvm.assume(i1 [[PRED0]]) 531; CHECK-NEXT: ret i1 false 532; 533 %pred0 = icmp ne i8 %x, 0 534 call void @llvm.assume(i1 %pred0) 535 %v = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y) 536 %or = or i8 %v, %z 537 %r = icmp eq i8 %or, 0 538 ret i1 %r 539} 540 541define i1 @fshr_non_zero_fail(i8 %x, i8 %y, i8 %z, i8 %w) { 542; CHECK-LABEL: @fshr_non_zero_fail( 543; CHECK-NEXT: [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0 544; CHECK-NEXT: call void @llvm.assume(i1 [[PRED0]]) 545; CHECK-NEXT: [[PRED1:%.*]] = icmp ne i8 [[W:%.*]], 0 546; CHECK-NEXT: call void @llvm.assume(i1 [[PRED1]]) 547; CHECK-NEXT: [[V:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X]], i8 [[W]], i8 [[Y:%.*]]) 548; CHECK-NEXT: [[OR:%.*]] = or i8 [[V]], [[Z:%.*]] 549; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[OR]], 0 550; CHECK-NEXT: ret i1 [[R]] 551; 552 %pred0 = icmp ne i8 %x, 0 553 call void @llvm.assume(i1 %pred0) 554 %pred1 = icmp ne i8 %w, 0 555 call void @llvm.assume(i1 %pred1) 556 %v = tail call i8 @llvm.fshr.i8(i8 %x, i8 %w, i8 %y) 557 %or = or i8 %v, %z 558 %r = icmp eq i8 %or, 0 559 ret i1 %r 560} 561 562define i1 @fshl_non_zero(i8 %x, i8 %y, i8 %z) { 563; CHECK-LABEL: @fshl_non_zero( 564; CHECK-NEXT: [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0 565; CHECK-NEXT: call void @llvm.assume(i1 [[PRED0]]) 566; CHECK-NEXT: ret i1 false 567; 568 %pred0 = icmp ne i8 %x, 0 569 call void @llvm.assume(i1 %pred0) 570 %v = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y) 571 %or = or i8 %v, %z 572 %r = icmp eq i8 %or, 0 573 ret i1 %r 574} 575 576define i1 @fshl_non_zero_fail(i8 %x, i8 %y, i8 %z, i8 %w) { 577; CHECK-LABEL: @fshl_non_zero_fail( 578; CHECK-NEXT: [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0 579; CHECK-NEXT: call void @llvm.assume(i1 [[PRED0]]) 580; CHECK-NEXT: [[PRED1:%.*]] = icmp ne i8 [[W:%.*]], 0 581; CHECK-NEXT: call void @llvm.assume(i1 [[PRED1]]) 582; CHECK-NEXT: [[V:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X]], i8 [[W]], i8 [[Y:%.*]]) 583; CHECK-NEXT: [[OR:%.*]] = or i8 [[V]], [[Z:%.*]] 584; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[OR]], 0 585; CHECK-NEXT: ret i1 [[R]] 586; 587 %pred0 = icmp ne i8 %x, 0 588 call void @llvm.assume(i1 %pred0) 589 %pred1 = icmp ne i8 %w, 0 590 call void @llvm.assume(i1 %pred1) 591 %v = tail call i8 @llvm.fshl.i8(i8 %x, i8 %w, i8 %y) 592 %or = or i8 %v, %z 593 %r = icmp eq i8 %or, 0 594 ret i1 %r 595} 596 597define i1 @bitcast_nonzero(<2 x i8> %xx, i16 %ind) { 598; CHECK-LABEL: @bitcast_nonzero( 599; CHECK-NEXT: ret i1 false 600; 601 %xa = add nuw nsw <2 x i8> %xx, <i8 1, i8 1> 602 %x = bitcast <2 x i8> %xa to i16 603 %z = or i16 %x, %ind 604 %r = icmp eq i16 %z, 0 605 ret i1 %r 606} 607 608define i1 @bitcast_todo_partial_nonzero_vec_to_int(<2 x i8> %xx, i16 %ind) { 609; CHECK-LABEL: @bitcast_todo_partial_nonzero_vec_to_int( 610; CHECK-NEXT: [[XA:%.*]] = add nuw nsw <2 x i8> [[XX:%.*]], <i8 1, i8 0> 611; CHECK-NEXT: [[X:%.*]] = bitcast <2 x i8> [[XA]] to i16 612; CHECK-NEXT: [[Z:%.*]] = or i16 [[X]], [[IND:%.*]] 613; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[Z]], 0 614; CHECK-NEXT: ret i1 [[R]] 615; 616 %xa = add nuw nsw <2 x i8> %xx, <i8 1, i8 0> 617 %x = bitcast <2 x i8> %xa to i16 618 %z = or i16 %x, %ind 619 %r = icmp eq i16 %z, 0 620 ret i1 %r 621} 622 623define <2 x i1> @bitcast_fail_nonzero_int_to_vec(i16 %xx, <2 x i8> %ind) { 624; CHECK-LABEL: @bitcast_fail_nonzero_int_to_vec( 625; CHECK-NEXT: [[XA:%.*]] = add nuw nsw i16 [[XX:%.*]], 1 626; CHECK-NEXT: [[X:%.*]] = bitcast i16 [[XA]] to <2 x i8> 627; CHECK-NEXT: [[Z:%.*]] = or <2 x i8> [[X]], [[IND:%.*]] 628; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[Z]], zeroinitializer 629; CHECK-NEXT: ret <2 x i1> [[R]] 630; 631 %xa = add nuw nsw i16 %xx, 1 632 %x = bitcast i16 %xa to <2 x i8> 633 %z = or <2 x i8> %x, %ind 634 %r = icmp eq <2 x i8> %z, zeroinitializer 635 ret <2 x i1> %r 636} 637 638define <2 x i1> @bitcast_veci8_to_veci16(<4 x i8> %xx, <2 x i16> %ind) { 639; CHECK-LABEL: @bitcast_veci8_to_veci16( 640; CHECK-NEXT: ret <2 x i1> zeroinitializer 641; 642 %xa = add nuw nsw <4 x i8> %xx, <i8 1, i8 1, i8 1, i8 1> 643 %x = bitcast <4 x i8> %xa to <2 x i16> 644 %z = or <2 x i16> %x, %ind 645 %r = icmp eq <2 x i16> %z, zeroinitializer 646 ret <2 x i1> %r 647} 648 649define <3 x i1> @bitcast_veci3_to_veci4_fail_not_multiple(<4 x i3> %xx, <3 x i4> %ind) { 650; CHECK-LABEL: @bitcast_veci3_to_veci4_fail_not_multiple( 651; CHECK-NEXT: [[XA:%.*]] = add nuw nsw <4 x i3> [[XX:%.*]], splat (i3 1) 652; CHECK-NEXT: [[X:%.*]] = bitcast <4 x i3> [[XA]] to <3 x i4> 653; CHECK-NEXT: [[Z:%.*]] = or <3 x i4> [[X]], [[IND:%.*]] 654; CHECK-NEXT: [[R:%.*]] = icmp eq <3 x i4> [[Z]], zeroinitializer 655; CHECK-NEXT: ret <3 x i1> [[R]] 656; 657 %xa = add nuw nsw <4 x i3> %xx, <i3 1, i3 1, i3 1, i3 1> 658 %x = bitcast <4 x i3> %xa to <3 x i4> 659 %z = or <3 x i4> %x, %ind 660 %r = icmp eq <3 x i4> %z, zeroinitializer 661 ret <3 x i1> %r 662} 663 664define <4 x i1> @bitcast_fail_veci16_to_veci8(<2 x i16> %xx, <4 x i8> %ind) { 665; CHECK-LABEL: @bitcast_fail_veci16_to_veci8( 666; CHECK-NEXT: [[XA:%.*]] = add nuw nsw <2 x i16> [[XX:%.*]], splat (i16 1) 667; CHECK-NEXT: [[X:%.*]] = bitcast <2 x i16> [[XA]] to <4 x i8> 668; CHECK-NEXT: [[Z:%.*]] = or <4 x i8> [[X]], [[IND:%.*]] 669; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i8> [[Z]], zeroinitializer 670; CHECK-NEXT: ret <4 x i1> [[R]] 671; 672 %xa = add nuw nsw <2 x i16> %xx, <i16 1, i16 1> 673 %x = bitcast <2 x i16> %xa to <4 x i8> 674 %z = or <4 x i8> %x, %ind 675 %r = icmp eq <4 x i8> %z, zeroinitializer 676 ret <4 x i1> %r 677} 678 679define i1 @bitcast_nonzero_fail_dont_check_float(float %xx, i32 %ind) { 680; CHECK-LABEL: @bitcast_nonzero_fail_dont_check_float( 681; CHECK-NEXT: [[XA:%.*]] = call float @llvm.maximum.f32(float [[XX:%.*]], float 1.000000e+00) 682; CHECK-NEXT: [[X:%.*]] = bitcast float [[XA]] to i32 683; CHECK-NEXT: [[Z:%.*]] = or i32 [[X]], [[IND:%.*]] 684; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[Z]], 0 685; CHECK-NEXT: ret i1 [[R]] 686; 687 %xa = call float @llvm.maximum.f32(float %xx, float 1.000000e+00) 688 %x = bitcast float %xa to i32 689 %z = or i32 %x, %ind 690 %r = icmp eq i32 %z, 0 691 ret i1 %r 692} 693 694define i1 @ctlz_true_nonzero(i8 %xx, i8 %ind) { 695; CHECK-LABEL: @ctlz_true_nonzero( 696; CHECK-NEXT: ret i1 false 697; 698 %xs = lshr i8 %xx, 1 699 %x = call i8 @llvm.ctlz.i8(i8 %xs, i1 true) 700 %z = or i8 %x, %ind 701 %r = icmp eq i8 %z, 0 702 ret i1 %r 703} 704 705define i1 @ctlz_false_nonzero(i8 %xx, i8 %ind) { 706; CHECK-LABEL: @ctlz_false_nonzero( 707; CHECK-NEXT: ret i1 false 708; 709 %xa = and i8 %xx, 127 710 %x = call i8 @llvm.ctlz.i8(i8 %xa, i1 true) 711 %z = or i8 %x, %ind 712 %r = icmp eq i8 %z, 0 713 ret i1 %r 714} 715 716define i1 @ctlz_nonzero_fail_maybe_neg(i8 %xx, i8 %ind) { 717; CHECK-LABEL: @ctlz_nonzero_fail_maybe_neg( 718; CHECK-NEXT: [[XS:%.*]] = ashr i8 [[XX:%.*]], 1 719; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.ctlz.i8(i8 [[XS]], i1 true) 720; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 721; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 722; CHECK-NEXT: ret i1 [[R]] 723; 724 %xs = ashr i8 %xx, 1 725 %x = call i8 @llvm.ctlz.i8(i8 %xs, i1 true) 726 %z = or i8 %x, %ind 727 %r = icmp eq i8 %z, 0 728 ret i1 %r 729} 730 731define i1 @cttz_true_nonzero(i8 %xx, i8 %ind) { 732; CHECK-LABEL: @cttz_true_nonzero( 733; CHECK-NEXT: ret i1 false 734; 735 %xs = shl i8 %xx, 1 736 %x = call i8 @llvm.cttz.i8(i8 %xs, i1 true) 737 %z = or i8 %x, %ind 738 %r = icmp eq i8 %z, 0 739 ret i1 %r 740} 741 742define i1 @cttz_false_nonzero(i8 %xx, i8 %ind) { 743; CHECK-LABEL: @cttz_false_nonzero( 744; CHECK-NEXT: ret i1 false 745; 746 %xa = and i8 %xx, -2 747 %x = call i8 @llvm.cttz.i8(i8 %xa, i1 true) 748 %z = or i8 %x, %ind 749 %r = icmp eq i8 %z, 0 750 ret i1 %r 751} 752 753define i1 @cttz_nonzero_fail_maybe_odd(i8 %xx, i8 %cnt, i8 %ind) { 754; CHECK-LABEL: @cttz_nonzero_fail_maybe_odd( 755; CHECK-NEXT: [[XS:%.*]] = shl i8 [[XX:%.*]], [[CNT:%.*]] 756; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.cttz.i8(i8 [[XS]], i1 true) 757; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 758; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 759; CHECK-NEXT: ret i1 [[R]] 760; 761 %xs = shl i8 %xx, %cnt 762 %x = call i8 @llvm.cttz.i8(i8 %xs, i1 true) 763 %z = or i8 %x, %ind 764 %r = icmp eq i8 %z, 0 765 ret i1 %r 766} 767 768define i1 @mul_nonzero_odd(i8 %xx, i8 %y, i8 %ind) { 769; CHECK-LABEL: @mul_nonzero_odd( 770; CHECK-NEXT: [[Y_NZ:%.*]] = icmp ne i8 [[Y:%.*]], 0 771; CHECK-NEXT: call void @llvm.assume(i1 [[Y_NZ]]) 772; CHECK-NEXT: ret i1 false 773; 774 %xo = or i8 %xx, 1 775 %y_nz = icmp ne i8 %y, 0 776 call void @llvm.assume(i1 %y_nz) 777 %x = mul i8 %xo, %y 778 %z = or i8 %x, %ind 779 %r = icmp eq i8 %z, 0 780 ret i1 %r 781} 782 783define i1 @mul_nonzero_odd_fail_y_maybe_zero(i8 %xx, i8 %y, i8 %ind) { 784; CHECK-LABEL: @mul_nonzero_odd_fail_y_maybe_zero( 785; CHECK-NEXT: [[XO:%.*]] = or i8 [[XX:%.*]], 1 786; CHECK-NEXT: [[X:%.*]] = mul i8 [[XO]], [[Y:%.*]] 787; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 788; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 789; CHECK-NEXT: ret i1 [[R]] 790; 791 %xo = or i8 %xx, 1 792 %x = mul i8 %xo, %y 793 %z = or i8 %x, %ind 794 %r = icmp eq i8 %z, 0 795 ret i1 %r 796} 797 798define i1 @sshl_nonzero(i8 %xx, i8 %y, i8 %ind) { 799; CHECK-LABEL: @sshl_nonzero( 800; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0 801; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 802; CHECK-NEXT: ret i1 false 803; 804 %x_nz = icmp ne i8 %xx, 0 805 call void @llvm.assume(i1 %x_nz) 806 %x = call i8 @llvm.sshl.sat.i8(i8 %xx, i8 %y) 807 %z = or i8 %x, %ind 808 %r = icmp eq i8 %z, 0 809 ret i1 %r 810} 811 812define i1 @sshl_nonzero_fail_x_maybe_z(i8 %xx, i8 %y, i8 %ind) { 813; CHECK-LABEL: @sshl_nonzero_fail_x_maybe_z( 814; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.sshl.sat.i8(i8 [[XX:%.*]], i8 [[Y:%.*]]) 815; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 816; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 817; CHECK-NEXT: ret i1 [[R]] 818; 819 %x = call i8 @llvm.sshl.sat.i8(i8 %xx, i8 %y) 820 %z = or i8 %x, %ind 821 %r = icmp eq i8 %z, 0 822 ret i1 %r 823} 824 825define i1 @ushl_nonzero(i8 %xx, i8 %y, i8 %ind) { 826; CHECK-LABEL: @ushl_nonzero( 827; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0 828; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 829; CHECK-NEXT: ret i1 false 830; 831 %x_nz = icmp ne i8 %xx, 0 832 call void @llvm.assume(i1 %x_nz) 833 %x = call i8 @llvm.ushl.sat.i8(i8 %xx, i8 %y) 834 %z = or i8 %x, %ind 835 %r = icmp eq i8 %z, 0 836 ret i1 %r 837} 838 839define i1 @ushl_nonzero_fail_x_maybe_z(i8 %xx, i8 %y, i8 %ind) { 840; CHECK-LABEL: @ushl_nonzero_fail_x_maybe_z( 841; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.ushl.sat.i8(i8 [[XX:%.*]], i8 [[Y:%.*]]) 842; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 843; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 844; CHECK-NEXT: ret i1 [[R]] 845; 846 %x = call i8 @llvm.ushl.sat.i8(i8 %xx, i8 %y) 847 %z = or i8 %x, %ind 848 %r = icmp eq i8 %z, 0 849 ret i1 %r 850} 851 852define i1 @ssub_sat_nonzero(i8 %xx, i8 %yy, i8 %ind) { 853; CHECK-LABEL: @ssub_sat_nonzero( 854; CHECK-NEXT: ret i1 false 855; 856 %xa = and i8 %xx, 191 857 %yo = or i8 %yy, 64 858 %x = call i8 @llvm.ssub.sat.i8(i8 %xa, i8 %yo) 859 %z = or i8 %x, %ind 860 %r = icmp eq i8 %z, 0 861 ret i1 %r 862} 863 864define i1 @ssub_sat_nonzero_ne_known_bits_fail_overlap(i8 %xx, i8 %yy, i8 %ind) { 865; CHECK-LABEL: @ssub_sat_nonzero_ne_known_bits_fail_overlap( 866; CHECK-NEXT: [[XA:%.*]] = and i8 [[XX:%.*]], -64 867; CHECK-NEXT: [[YO:%.*]] = or i8 [[YY:%.*]], 64 868; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[XA]], i8 [[YO]]) 869; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 870; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 871; CHECK-NEXT: ret i1 [[R]] 872; 873 %xa = and i8 %xx, 192 874 %yo = or i8 %yy, 64 875 %x = call i8 @llvm.ssub.sat.i8(i8 %xa, i8 %yo) 876 %z = or i8 %x, %ind 877 %r = icmp eq i8 %z, 0 878 ret i1 %r 879} 880 881define i1 @usub_sat_nonzero(i8 %xx, i8 %yy, i8 %ind) { 882; CHECK-LABEL: @usub_sat_nonzero( 883; CHECK-NEXT: [[Y_ULT_31:%.*]] = icmp ult i8 [[YY:%.*]], 31 884; CHECK-NEXT: call void @llvm.assume(i1 [[Y_ULT_31]]) 885; CHECK-NEXT: [[XO:%.*]] = or i8 [[XX:%.*]], 34 886; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[XO]], i8 [[YY]]) 887; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 888; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 889; CHECK-NEXT: ret i1 [[R]] 890; 891 %y_ult_31 = icmp ult i8 %yy, 31 892 call void @llvm.assume(i1 %y_ult_31) 893 %xo = or i8 %xx, 34 894 %x = call i8 @llvm.usub.sat.i8(i8 %xo, i8 %yy) 895 %z = or i8 %x, %ind 896 %r = icmp eq i8 %z, 0 897 ret i1 %r 898} 899 900define i1 @usub_sat_nonzero_fail(i8 %xx, i8 %yy, i8 %ind) { 901; CHECK-LABEL: @usub_sat_nonzero_fail( 902; CHECK-NEXT: [[XA:%.*]] = and i8 [[XX:%.*]], 16 903; CHECK-NEXT: [[YO:%.*]] = or i8 [[YY:%.*]], 7 904; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[XA]], i8 [[YO]]) 905; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 906; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 907; CHECK-NEXT: ret i1 [[R]] 908; 909 %xa = and i8 %xx, 16 910 %yo = or i8 %yy, 7 911 %x = call i8 @llvm.usub.sat.i8(i8 %xa, i8 %yo) 912 %z = or i8 %x, %ind 913 %r = icmp eq i8 %z, 0 914 ret i1 %r 915} 916 917define i1 @sadd_sat_nonzero(i8 %xx, i8 %yy, i8 %ind) { 918; CHECK-LABEL: @sadd_sat_nonzero( 919; CHECK-NEXT: [[X_STRICT_POS:%.*]] = icmp sgt i8 [[XX:%.*]], 0 920; CHECK-NEXT: [[Y_POS:%.*]] = icmp sge i8 [[YY:%.*]], 0 921; CHECK-NEXT: call void @llvm.assume(i1 [[X_STRICT_POS]]) 922; CHECK-NEXT: call void @llvm.assume(i1 [[Y_POS]]) 923; CHECK-NEXT: ret i1 false 924; 925 %x_strict_pos = icmp sgt i8 %xx, 0 926 %y_pos = icmp sge i8 %yy, 0 927 call void @llvm.assume(i1 %x_strict_pos) 928 call void @llvm.assume(i1 %y_pos) 929 %x = call i8 @llvm.sadd.sat.i8(i8 %xx, i8 %yy) 930 %z = or i8 %x, %ind 931 %r = icmp eq i8 %z, 0 932 ret i1 %r 933} 934 935define i1 @sadd_sat_nonzero_fail_maybe_zz(i8 %xx, i8 %yy, i8 %ind) { 936; CHECK-LABEL: @sadd_sat_nonzero_fail_maybe_zz( 937; CHECK-NEXT: [[X_POS:%.*]] = icmp sge i8 [[XX:%.*]], 0 938; CHECK-NEXT: [[Y_POS:%.*]] = icmp sge i8 [[YY:%.*]], 0 939; CHECK-NEXT: call void @llvm.assume(i1 [[X_POS]]) 940; CHECK-NEXT: call void @llvm.assume(i1 [[Y_POS]]) 941; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[XX]], i8 [[YY]]) 942; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 943; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 944; CHECK-NEXT: ret i1 [[R]] 945; 946 %x_pos = icmp sge i8 %xx, 0 947 %y_pos = icmp sge i8 %yy, 0 948 call void @llvm.assume(i1 %x_pos) 949 call void @llvm.assume(i1 %y_pos) 950 %x = call i8 @llvm.sadd.sat.i8(i8 %xx, i8 %yy) 951 %z = or i8 %x, %ind 952 %r = icmp eq i8 %z, 0 953 ret i1 %r 954} 955 956define i1 @umax_nonzero(i8 %xx, i8 %yy, i8 %ind) { 957; CHECK-LABEL: @umax_nonzero( 958; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0 959; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 960; CHECK-NEXT: ret i1 false 961; 962 %x_nz = icmp ne i8 %xx, 0 963 call void @llvm.assume(i1 %x_nz) 964 %x = call i8 @llvm.umax.i8(i8 %xx, i8 %yy) 965 %z = or i8 %x, %ind 966 %r = icmp eq i8 %z, 0 967 ret i1 %r 968} 969 970define i1 @umax_nonzero_fail_x_maybe_z(i8 %xx, i8 %yy, i8 %ind) { 971; CHECK-LABEL: @umax_nonzero_fail_x_maybe_z( 972; CHECK-NEXT: [[X_NZ:%.*]] = icmp sge i8 [[XX:%.*]], 0 973; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 974; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.umax.i8(i8 [[XX]], i8 [[YY:%.*]]) 975; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 976; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 977; CHECK-NEXT: ret i1 [[R]] 978; 979 %x_nz = icmp sge i8 %xx, 0 980 call void @llvm.assume(i1 %x_nz) 981 %x = call i8 @llvm.umax.i8(i8 %xx, i8 %yy) 982 %z = or i8 %x, %ind 983 %r = icmp eq i8 %z, 0 984 ret i1 %r 985} 986 987define i1 @umin_nonzero(i8 %xx, i8 %yy, i8 %ind) { 988; CHECK-LABEL: @umin_nonzero( 989; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0 990; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 991; CHECK-NEXT: [[Y_NZ:%.*]] = icmp ne i8 [[YY:%.*]], 0 992; CHECK-NEXT: call void @llvm.assume(i1 [[Y_NZ]]) 993; CHECK-NEXT: ret i1 false 994; 995 %x_nz = icmp ne i8 %xx, 0 996 call void @llvm.assume(i1 %x_nz) 997 %y_nz = icmp ne i8 %yy, 0 998 call void @llvm.assume(i1 %y_nz) 999 %x = call i8 @llvm.umin.i8(i8 %xx, i8 %yy) 1000 %z = or i8 %x, %ind 1001 %r = icmp eq i8 %z, 0 1002 ret i1 %r 1003} 1004 1005define i1 @umin_nonzero_fail_y_maybe_z(i8 %xx, i8 %yy, i8 %ind) { 1006; CHECK-LABEL: @umin_nonzero_fail_y_maybe_z( 1007; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0 1008; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 1009; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.umin.i8(i8 [[XX]], i8 [[YY:%.*]]) 1010; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 1011; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 1012; CHECK-NEXT: ret i1 [[R]] 1013; 1014 %x_nz = icmp ne i8 %xx, 0 1015 call void @llvm.assume(i1 %x_nz) 1016 %x = call i8 @llvm.umin.i8(i8 %xx, i8 %yy) 1017 %z = or i8 %x, %ind 1018 %r = icmp eq i8 %z, 0 1019 ret i1 %r 1020} 1021 1022define i1 @smin_nonzero(i8 %xx, i8 %yy, i8 %ind) { 1023; CHECK-LABEL: @smin_nonzero( 1024; CHECK-NEXT: [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0 1025; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 1026; CHECK-NEXT: [[Y_NZ:%.*]] = icmp ne i8 [[YY:%.*]], 0 1027; CHECK-NEXT: call void @llvm.assume(i1 [[Y_NZ]]) 1028; CHECK-NEXT: ret i1 false 1029; 1030 %x_nz = icmp ne i8 %xx, 0 1031 call void @llvm.assume(i1 %x_nz) 1032 %y_nz = icmp ne i8 %yy, 0 1033 call void @llvm.assume(i1 %y_nz) 1034 %x = call i8 @llvm.umin.i8(i8 %xx, i8 %yy) 1035 %z = or i8 %x, %ind 1036 %r = icmp eq i8 %z, 0 1037 ret i1 %r 1038} 1039 1040define i1 @smin_nonzero_neg_arg(i8 %xx, i8 %yy, i8 %ind) { 1041; CHECK-LABEL: @smin_nonzero_neg_arg( 1042; CHECK-NEXT: [[X_NEG:%.*]] = icmp slt i8 [[XX:%.*]], 0 1043; CHECK-NEXT: call void @llvm.assume(i1 [[X_NEG]]) 1044; CHECK-NEXT: ret i1 false 1045; 1046 %x_neg = icmp slt i8 %xx, 0 1047 call void @llvm.assume(i1 %x_neg) 1048 %x = call i8 @llvm.smin.i8(i8 %xx, i8 %yy) 1049 %z = or i8 %x, %ind 1050 %r = icmp eq i8 %z, 0 1051 ret i1 %r 1052} 1053 1054define i1 @smin_nonzero_fail_y_maybe_z(i8 %xx, i8 %yy, i8 %ind) { 1055; CHECK-LABEL: @smin_nonzero_fail_y_maybe_z( 1056; CHECK-NEXT: [[X_NZ:%.*]] = icmp sle i8 [[XX:%.*]], 0 1057; CHECK-NEXT: call void @llvm.assume(i1 [[X_NZ]]) 1058; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.smin.i8(i8 [[XX]], i8 [[YY:%.*]]) 1059; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 1060; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 1061; CHECK-NEXT: ret i1 [[R]] 1062; 1063 %x_nz = icmp sle i8 %xx, 0 1064 call void @llvm.assume(i1 %x_nz) 1065 %x = call i8 @llvm.smin.i8(i8 %xx, i8 %yy) 1066 %z = or i8 %x, %ind 1067 %r = icmp eq i8 %z, 0 1068 ret i1 %r 1069} 1070 1071define i1 @smax_nonzero_pos_arg(i8 %xx, i8 %yy, i8 %ind) { 1072; CHECK-LABEL: @smax_nonzero_pos_arg( 1073; CHECK-NEXT: ret i1 false 1074; 1075 %ya = and i8 %yy, 127 1076 %yo = or i8 %ya, 1 1077 %x = call i8 @llvm.smax.i8(i8 %xx, i8 %yo) 1078 %z = or i8 %x, %ind 1079 %r = icmp eq i8 %z, 0 1080 ret i1 %r 1081} 1082 1083define i1 @smax_nonzero_pos_arg_fail_nonstrict_pos(i8 %xx, i8 %yy, i8 %ind) { 1084; CHECK-LABEL: @smax_nonzero_pos_arg_fail_nonstrict_pos( 1085; CHECK-NEXT: [[Y_POS:%.*]] = icmp sge i8 [[YY:%.*]], 0 1086; CHECK-NEXT: call void @llvm.assume(i1 [[Y_POS]]) 1087; CHECK-NEXT: [[X:%.*]] = call i8 @llvm.smax.i8(i8 [[XX:%.*]], i8 [[YY]]) 1088; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[IND:%.*]] 1089; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z]], 0 1090; CHECK-NEXT: ret i1 [[R]] 1091; 1092 %y_pos = icmp sge i8 %yy, 0 1093 call void @llvm.assume(i1 %y_pos) 1094 %x = call i8 @llvm.smax.i8(i8 %xx, i8 %yy) 1095 %z = or i8 %x, %ind 1096 %r = icmp eq i8 %z, 0 1097 ret i1 %r 1098} 1099 1100define i1 @mul_nonzero_contains_nonzero_mul(i8 %x, i8 %y) { 1101; CHECK-LABEL: @mul_nonzero_contains_nonzero_mul( 1102; CHECK-NEXT: ret i1 true 1103; 1104 %xx = or i8 %x, 16 1105 %yy = or i8 %y, 8 1106 %xy = mul i8 %xx, %yy 1107 %nz = icmp ne i8 %xy, 0 1108 ret i1 %nz 1109} 1110 1111define i1 @src_mul_maybe_zero_no_nonzero_mul(i8 %x, i8 %y) { 1112; CHECK-LABEL: @src_mul_maybe_zero_no_nonzero_mul( 1113; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 96 1114; CHECK-NEXT: [[YY:%.*]] = or i8 [[Y:%.*]], 8 1115; CHECK-NEXT: [[XY:%.*]] = mul i8 [[XX]], [[YY]] 1116; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[XY]], 0 1117; CHECK-NEXT: ret i1 [[NZ]] 1118; 1119 %xx = or i8 %x, 96 1120 %yy = or i8 %y, 8 1121 %xy = mul i8 %xx, %yy 1122 %nz = icmp ne i8 %xy, 0 1123 ret i1 %nz 1124} 1125 1126define i1 @sdiv_known_non_zero(i8 %x, i8 %y) { 1127; CHECK-LABEL: @sdiv_known_non_zero( 1128; CHECK-NEXT: ret i1 true 1129; 1130 %xx0 = or i8 %x, 135 1131 %xx = and i8 %xx0, -2 1132 %xy = sdiv i8 %xx, -2 1133 %nz = icmp ne i8 %xy, 0 1134 ret i1 %nz 1135} 1136 1137define i1 @sdiv_known_non_zero2(i8 %x, i8 %y) { 1138; CHECK-LABEL: @sdiv_known_non_zero2( 1139; CHECK-NEXT: ret i1 true 1140; 1141 %xx0 = or i8 %x, 15 1142 %xx = and i8 %xx0, -4 1143 %yy = and i8 %y, 3 1144 %xy = sdiv i8 %xx, %yy 1145 %nz = icmp ne i8 %xy, 0 1146 ret i1 %nz 1147} 1148 1149define i1 @sdiv_known_non_zero_fail(i8 %x, i8 %y) { 1150; CHECK-LABEL: @sdiv_known_non_zero_fail( 1151; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 15 1152; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y:%.*]], 3 1153; CHECK-NEXT: [[XY:%.*]] = sdiv i8 [[XX]], [[YY]] 1154; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[XY]], 0 1155; CHECK-NEXT: ret i1 [[NZ]] 1156; 1157 %xx = or i8 %x, 15 1158 %yy = and i8 %y, 3 1159 %xy = sdiv i8 %xx, %yy 1160 %nz = icmp ne i8 %xy, 0 1161 ret i1 %nz 1162} 1163 1164define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec(<2 x i8> %a, <2 x i8> %b) { 1165; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec( 1166; CHECK-NEXT: ret <2 x i1> zeroinitializer 1167; 1168 %c = icmp sge <2 x i8> %a, <i8 1, i8 4> 1169 %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5> 1170 %and = or <2 x i8> %s, %b 1171 %r = icmp eq <2 x i8> %and, zeroinitializer 1172 ret <2 x i1> %r 1173} 1174 1175define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec_wundef(<2 x i8> %a, <2 x i8> %b) { 1176; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec_wundef( 1177; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i8> [[A:%.*]], <i8 1, i8 undef> 1178; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[A]], <2 x i8> <i8 4, i8 5> 1179; CHECK-NEXT: [[AND:%.*]] = or <2 x i8> [[S]], [[B:%.*]] 1180; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer 1181; CHECK-NEXT: ret <2 x i1> [[R]] 1182; 1183 %c = icmp sge <2 x i8> %a, <i8 1, i8 undef> 1184 %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5> 1185 %and = or <2 x i8> %s, %b 1186 %r = icmp eq <2 x i8> %and, zeroinitializer 1187 ret <2 x i1> %r 1188} 1189 1190define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec_wpoison(<2 x i8> %a, <2 x i8> %b) { 1191; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec_wpoison( 1192; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i8> [[A:%.*]], <i8 1, i8 poison> 1193; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[A]], <2 x i8> <i8 4, i8 5> 1194; CHECK-NEXT: [[AND:%.*]] = or <2 x i8> [[S]], [[B:%.*]] 1195; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer 1196; CHECK-NEXT: ret <2 x i1> [[R]] 1197; 1198 %c = icmp sge <2 x i8> %a, <i8 1, i8 poison> 1199 %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5> 1200 %and = or <2 x i8> %s, %b 1201 %r = icmp eq <2 x i8> %and, zeroinitializer 1202 ret <2 x i1> %r 1203} 1204 1205define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec_fail(<2 x i8> %a, <2 x i8> %b) { 1206; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec_fail( 1207; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i8> [[A:%.*]], <i8 0, i8 4> 1208; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[A]], <2 x i8> <i8 4, i8 5> 1209; CHECK-NEXT: [[AND:%.*]] = or <2 x i8> [[S]], [[B:%.*]] 1210; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer 1211; CHECK-NEXT: ret <2 x i1> [[R]] 1212; 1213 %c = icmp sge <2 x i8> %a, <i8 0, i8 4> 1214 %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5> 1215 %and = or <2 x i8> %s, %b 1216 %r = icmp eq <2 x i8> %and, zeroinitializer 1217 ret <2 x i1> %r 1218} 1219 1220define i1 @sub_via_non_eq(i8 %x, i8 %y) { 1221; CHECK-LABEL: @sub_via_non_eq( 1222; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0 1223; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 1224; CHECK-NEXT: ret i1 false 1225; 1226 %ne = icmp ne i8 %x, 0 1227 call void @llvm.assume(i1 %ne) 1228 %shl = shl nuw i8 %x, 3 1229 %sub = sub i8 %x, %shl 1230 %cmp = icmp eq i8 %sub, 0 1231 ret i1 %cmp 1232} 1233 1234; Test mismatch of ptrtoints type and pointer size 1235define i1 @recursiveGEP_orcmp_truncPtr(ptr %val1, i32 %val2) { 1236; CHECK-LABEL: @recursiveGEP_orcmp_truncPtr( 1237; CHECK-NEXT: entry: 1238; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 1239; CHECK: while.cond.i: 1240; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 1241; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1 1242; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 1243; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 1244; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 1245; CHECK: while.end.i: 1246; CHECK-NEXT: [[SUB_PTR_LHS_CAST_I:%.*]] = ptrtoint ptr [[TEST_0_I]] to i32 1247; CHECK-NEXT: [[SUB_PTR_RHS_CAST_I:%.*]] = ptrtoint ptr [[VAL1]] to i32 1248; CHECK-NEXT: [[SUB_PTR_SUB_I:%.*]] = sub i32 [[SUB_PTR_LHS_CAST_I]], [[SUB_PTR_RHS_CAST_I]] 1249; CHECK-NEXT: [[ORVAL:%.*]] = or i32 [[VAL2:%.*]], [[SUB_PTR_SUB_I]] 1250; CHECK-NEXT: [[BOOL:%.*]] = icmp eq i32 [[ORVAL]], 0 1251; CHECK-NEXT: ret i1 [[BOOL]] 1252; 1253entry: 1254 br label %while.cond.i 1255 1256while.cond.i: 1257 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 1258 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 1259 %0 = load i8, ptr %test.0.i, align 2 1260 %cmp3.not.i = icmp eq i8 %0, 0 1261 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 1262 1263while.end.i: 1264 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i32 1265 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i32 1266 %sub.ptr.sub.i = sub i32 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 1267 %orval = or i32 %val2, %sub.ptr.sub.i 1268 %bool = icmp eq i32 %orval, 0 1269 ret i1 %bool 1270} 1271 1272define i1 @check_get_vector_length(i32 %x, i32 %y) { 1273; CHECK-LABEL: @check_get_vector_length( 1274; CHECK-NEXT: [[NE:%.*]] = icmp ne i32 [[X:%.*]], 0 1275; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]] 1276; CHECK: true: 1277; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.experimental.get.vector.length.i32(i32 [[X]], i32 1, i1 true) 1278; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i32 [[Z]], [[Y:%.*]] 1279; CHECK-NEXT: ret i1 [[CMP0]] 1280; CHECK: false: 1281; CHECK-NEXT: ret i1 [[NE]] 1282; 1283 %ne = icmp ne i32 %x, 0 1284 br i1 %ne, label %true, label %false 1285true: 1286 %z = call i32 @llvm.experimental.get.vector.length.i32(i32 %x, i32 1, i1 true) 1287 %cmp0 = icmp ugt i32 %z, %y 1288 %cmp1 = icmp eq i32 %y, 0 1289 %r = or i1 %cmp0, %cmp1 1290 ret i1 %r 1291false: 1292 ret i1 %ne 1293} 1294 1295define <2 x i1> @range_metadata_vec(ptr %p, <2 x i32> %x) { 1296; CHECK-LABEL: @range_metadata_vec( 1297; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1298; 1299 %v = load <2 x i32>, ptr %p, !range !{i32 1, i32 100} 1300 %or = or <2 x i32> %v, %x 1301 %cmp = icmp ne <2 x i32> %or, zeroinitializer 1302 ret <2 x i1> %cmp 1303} 1304 1305define i1 @range_attr(i8 range(i8 1, 0) %x, i8 %y) { 1306; CHECK-LABEL: @range_attr( 1307; CHECK-NEXT: ret i1 false 1308; 1309 %or = or i8 %y, %x 1310 %cmp = icmp eq i8 %or, 0 1311 ret i1 %cmp 1312} 1313 1314define i1 @neg_range_attr(i8 range(i8 -1, 1) %x, i8 %y) { 1315; CHECK-LABEL: @neg_range_attr( 1316; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 1317; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0 1318; CHECK-NEXT: ret i1 [[CMP]] 1319; 1320 %or = or i8 %y, %x 1321 %cmp = icmp eq i8 %or, 0 1322 ret i1 %cmp 1323} 1324 1325declare range(i8 1, 0) i8 @returns_non_zero_range_helper() 1326declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper() 1327 1328define i1 @range_return(i8 %y) { 1329; CHECK-LABEL: @range_return( 1330; CHECK-NEXT: [[X:%.*]] = call i8 @returns_non_zero_range_helper() 1331; CHECK-NEXT: ret i1 false 1332; 1333 %x = call i8 @returns_non_zero_range_helper() 1334 %or = or i8 %y, %x 1335 %cmp = icmp eq i8 %or, 0 1336 ret i1 %cmp 1337} 1338 1339define i1 @neg_range_return(i8 %y) { 1340; CHECK-LABEL: @neg_range_return( 1341; CHECK-NEXT: [[X:%.*]] = call i8 @returns_contain_zero_range_helper() 1342; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X]] 1343; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0 1344; CHECK-NEXT: ret i1 [[CMP]] 1345; 1346 %x = call i8 @returns_contain_zero_range_helper() 1347 %or = or i8 %y, %x 1348 %cmp = icmp eq i8 %or, 0 1349 ret i1 %cmp 1350} 1351 1352declare i8 @returns_i8_helper() 1353 1354define i1 @range_call(i8 %y) { 1355; CHECK-LABEL: @range_call( 1356; CHECK-NEXT: [[X:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper() 1357; CHECK-NEXT: ret i1 false 1358; 1359 %x = call range(i8 1, 0) i8 @returns_i8_helper() 1360 %or = or i8 %y, %x 1361 %cmp = icmp eq i8 %or, 0 1362 ret i1 %cmp 1363} 1364 1365define i1 @neg_range_call(i8 %y) { 1366; CHECK-LABEL: @neg_range_call( 1367; CHECK-NEXT: [[X:%.*]] = call range(i8 -1, 1) i8 @returns_i8_helper() 1368; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X]] 1369; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0 1370; CHECK-NEXT: ret i1 [[CMP]] 1371; 1372 %x = call range(i8 -1, 1) i8 @returns_i8_helper() 1373 %or = or i8 %y, %x 1374 %cmp = icmp eq i8 %or, 0 1375 ret i1 %cmp 1376} 1377 1378define <2 x i1> @range_attr_vec(<2 x i8> range(i8 1, 0) %x, <2 x i8> %y) { 1379; CHECK-LABEL: @range_attr_vec( 1380; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1381; 1382 %or = or <2 x i8> %y, %x 1383 %cmp = icmp ne <2 x i8> %or, zeroinitializer 1384 ret <2 x i1> %cmp 1385} 1386 1387define <2 x i1> @neg_range_attr_vec(<2 x i8> range(i8 -1, 1) %x, <2 x i8> %y) { 1388; CHECK-LABEL: @neg_range_attr_vec( 1389; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]] 1390; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer 1391; CHECK-NEXT: ret <2 x i1> [[CMP]] 1392; 1393 %or = or <2 x i8> %y, %x 1394 %cmp = icmp ne <2 x i8> %or, zeroinitializer 1395 ret <2 x i1> %cmp 1396} 1397 1398declare range(i8 1, 0) <2 x i8> @returns_non_zero_range_helper_vec() 1399declare range(i8 -1, 1) <2 x i8> @returns_contain_zero_range_helper_vec() 1400 1401define <2 x i1> @range_return_vec(<2 x i8> %y) { 1402; CHECK-LABEL: @range_return_vec( 1403; CHECK-NEXT: [[X:%.*]] = call <2 x i8> @returns_non_zero_range_helper_vec() 1404; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1405; 1406 %x = call <2 x i8> @returns_non_zero_range_helper_vec() 1407 %or = or <2 x i8> %y, %x 1408 %cmp = icmp ne <2 x i8> %or, zeroinitializer 1409 ret <2 x i1> %cmp 1410} 1411 1412define <2 x i1> @neg_range_return_vec(<2 x i8> %y) { 1413; CHECK-LABEL: @neg_range_return_vec( 1414; CHECK-NEXT: [[X:%.*]] = call <2 x i8> @returns_contain_zero_range_helper_vec() 1415; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X]] 1416; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer 1417; CHECK-NEXT: ret <2 x i1> [[CMP]] 1418; 1419 %x = call <2 x i8> @returns_contain_zero_range_helper_vec() 1420 %or = or <2 x i8> %y, %x 1421 %cmp = icmp ne <2 x i8> %or, zeroinitializer 1422 ret <2 x i1> %cmp 1423} 1424 1425declare <2 x i8> @returns_i8_helper_vec() 1426 1427define <2 x i1> @range_call_vec(<2 x i8> %y) { 1428; CHECK-LABEL: @range_call_vec( 1429; CHECK-NEXT: [[X:%.*]] = call range(i8 1, 0) <2 x i8> @returns_i8_helper_vec() 1430; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1431; 1432 %x = call range(i8 1, 0) <2 x i8> @returns_i8_helper_vec() 1433 %or = or <2 x i8> %y, %x 1434 %cmp = icmp ne <2 x i8> %or, zeroinitializer 1435 ret <2 x i1> %cmp 1436} 1437 1438define <2 x i1> @neg_range_call_vec(<2 x i8> %y) { 1439; CHECK-LABEL: @neg_range_call_vec( 1440; CHECK-NEXT: [[X:%.*]] = call range(i8 -1, 1) <2 x i8> @returns_i8_helper_vec() 1441; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X]] 1442; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer 1443; CHECK-NEXT: ret <2 x i1> [[CMP]] 1444; 1445 %x = call range(i8 -1, 1) <2 x i8> @returns_i8_helper_vec() 1446 %or = or <2 x i8> %y, %x 1447 %cmp = icmp ne <2 x i8> %or, zeroinitializer 1448 ret <2 x i1> %cmp 1449} 1450 1451define i1 @trunc_nsw_non_zero(i8 %x) { 1452; CHECK-LABEL: @trunc_nsw_non_zero( 1453; CHECK-NEXT: [[X_NE_Z:%.*]] = icmp ne i8 [[X:%.*]], 0 1454; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_Z]]) 1455; CHECK-NEXT: ret i1 true 1456; 1457 %x_ne_z = icmp ne i8 %x, 0 1458 call void @llvm.assume(i1 %x_ne_z) 1459 %v = trunc nsw i8 %x to i4 1460 %r = icmp ne i4 %v, 0 1461 ret i1 %r 1462} 1463 1464define i1 @trunc_nuw_non_zero(i8 %xx) { 1465; CHECK-LABEL: @trunc_nuw_non_zero( 1466; CHECK-NEXT: ret i1 false 1467; 1468 %x = add nuw i8 %xx, 1 1469 %v = trunc nuw i8 %x to i4 1470 %r = icmp eq i4 %v, 0 1471 ret i1 %r 1472} 1473 1474define i1 @trunc_non_zero_fail(i8 %x) { 1475; CHECK-LABEL: @trunc_non_zero_fail( 1476; CHECK-NEXT: [[X_NE_Z:%.*]] = icmp ne i8 [[X:%.*]], 0 1477; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_Z]]) 1478; CHECK-NEXT: [[R:%.*]] = trunc i8 [[X]] to i1 1479; CHECK-NEXT: ret i1 [[R]] 1480; 1481 %x_ne_z = icmp ne i8 %x, 0 1482 call void @llvm.assume(i1 %x_ne_z) 1483 %r = trunc i8 %x to i1 1484 ret i1 %r 1485} 1486 1487define i1 @trunc_nsw_nuw_non_zero_fail(i8 %xx) { 1488; CHECK-LABEL: @trunc_nsw_nuw_non_zero_fail( 1489; CHECK-NEXT: [[X:%.*]] = add nsw i8 [[XX:%.*]], 1 1490; CHECK-NEXT: [[V:%.*]] = trunc nuw nsw i8 [[X]] to i4 1491; CHECK-NEXT: [[R:%.*]] = icmp eq i4 [[V]], 0 1492; CHECK-NEXT: ret i1 [[R]] 1493; 1494 %x = add nsw i8 %xx, 1 1495 %v = trunc nsw nuw i8 %x to i4 1496 %r = icmp eq i4 %v, 0 1497 ret i1 %r 1498} 1499 1500define <4 x i1> @vec_reverse_non_zero(<4 x i8> %xx) { 1501; CHECK-LABEL: @vec_reverse_non_zero( 1502; CHECK-NEXT: ret <4 x i1> zeroinitializer 1503; 1504 %x = add nuw <4 x i8> %xx, <i8 1, i8 1, i8 1, i8 1> 1505 %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x) 1506 %r = icmp eq <4 x i8> %rev, zeroinitializer 1507 ret <4 x i1> %r 1508} 1509 1510define <4 x i1> @vec_reverse_non_zero_fail(<4 x i8> %xx) { 1511; CHECK-LABEL: @vec_reverse_non_zero_fail( 1512; CHECK-NEXT: [[X:%.*]] = add nuw <4 x i8> [[XX:%.*]], <i8 1, i8 0, i8 1, i8 1> 1513; CHECK-NEXT: [[REV:%.*]] = call <4 x i8> @llvm.vector.reverse.v4i8(<4 x i8> [[X]]) 1514; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i8> [[REV]], zeroinitializer 1515; CHECK-NEXT: ret <4 x i1> [[R]] 1516; 1517 %x = add nuw <4 x i8> %xx, <i8 1, i8 0, i8 1, i8 1> 1518 %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x) 1519 %r = icmp eq <4 x i8> %rev, zeroinitializer 1520 ret <4 x i1> %r 1521} 1522 1523define i1 @vec_reverse_non_zero_demanded(<4 x i8> %xx) { 1524; CHECK-LABEL: @vec_reverse_non_zero_demanded( 1525; CHECK-NEXT: ret i1 false 1526; 1527 %x = add nuw <4 x i8> %xx, <i8 1, i8 0, i8 0, i8 0> 1528 %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x) 1529 %ele = extractelement <4 x i8> %rev, i64 3 1530 %r = icmp eq i8 %ele, 0 1531 ret i1 %r 1532} 1533 1534define i1 @vec_reverse_non_zero_demanded_fail(<4 x i8> %xx) { 1535; CHECK-LABEL: @vec_reverse_non_zero_demanded_fail( 1536; CHECK-NEXT: [[X:%.*]] = add nuw <4 x i8> [[XX:%.*]], <i8 1, i8 0, i8 0, i8 0> 1537; CHECK-NEXT: [[REV:%.*]] = call <4 x i8> @llvm.vector.reverse.v4i8(<4 x i8> [[X]]) 1538; CHECK-NEXT: [[ELE:%.*]] = extractelement <4 x i8> [[REV]], i64 2 1539; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ELE]], 0 1540; CHECK-NEXT: ret i1 [[R]] 1541; 1542 %x = add nuw <4 x i8> %xx, <i8 1, i8 0, i8 0, i8 0> 1543 %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x) 1544 %ele = extractelement <4 x i8> %rev, i64 2 1545 %r = icmp eq i8 %ele, 0 1546 ret i1 %r 1547} 1548 1549declare i32 @llvm.experimental.get.vector.length.i32(i32, i32, i1) 1550