1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3: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" 5 6declare void @usei8ptr(ptr %ptr) 7 8; Ensure that we do not crash when looking at such a weird bitcast. 9define i1 @bitcast_from_single_element_pointer_vector_to_pointer(<1 x ptr> %ptr1vec, ptr %ptr2) { 10; CHECK-LABEL: @bitcast_from_single_element_pointer_vector_to_pointer( 11; CHECK-NEXT: [[PTR1:%.*]] = bitcast <1 x ptr> [[PTR1VEC:%.*]] to ptr 12; CHECK-NEXT: call void @usei8ptr(ptr [[PTR1]]) 13; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[PTR1]], [[PTR2:%.*]] 14; CHECK-NEXT: ret i1 [[CMP]] 15; 16 %ptr1 = bitcast <1 x ptr> %ptr1vec to ptr 17 call void @usei8ptr(ptr %ptr1) 18 %cmp = icmp eq ptr %ptr1, %ptr2 19 ret i1 %cmp 20} 21 22define i1 @poison(i32 %x) { 23; CHECK-LABEL: @poison( 24; CHECK-NEXT: ret i1 poison 25; 26 %v = icmp eq i32 %x, poison 27 ret i1 %v 28} 29 30define i1 @poison2(i32 %x) { 31; CHECK-LABEL: @poison2( 32; CHECK-NEXT: ret i1 poison 33; 34 %v = icmp slt i32 %x, poison 35 ret i1 %v 36} 37 38define i1 @mul_div_cmp_smaller(i8 %x) { 39; CHECK-LABEL: @mul_div_cmp_smaller( 40; CHECK-NEXT: ret i1 true 41; 42 %mul = mul i8 %x, 3 43 %div = udiv i8 %mul, 4 44 %cmp = icmp ule i8 %div, %x 45 ret i1 %cmp 46} 47 48define i1 @mul_div_cmp_equal(i8 %x) { 49; CHECK-LABEL: @mul_div_cmp_equal( 50; CHECK-NEXT: ret i1 true 51; 52 %mul = mul i8 %x, 3 53 %div = udiv i8 %mul, 3 54 %cmp = icmp ule i8 %div, %x 55 ret i1 %cmp 56} 57 58; Negative test: 3>2 59define i1 @mul_div_cmp_greater(i8 %x) { 60; CHECK-LABEL: @mul_div_cmp_greater( 61; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 3 62; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[MUL]], 2 63; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[DIV]], [[X]] 64; CHECK-NEXT: ret i1 [[CMP]] 65; 66 %mul = mul i8 %x, 3 67 %div = udiv i8 %mul, 2 68 %cmp = icmp ule i8 %div, %x 69 ret i1 %cmp 70} 71define i1 @mul_div_cmp_ugt(i8 %x) { 72; CHECK-LABEL: @mul_div_cmp_ugt( 73; CHECK-NEXT: ret i1 false 74; 75 %mul = mul i8 %x, 3 76 %div = udiv i8 %mul, 4 77 %cmp = icmp ugt i8 %div, %x 78 ret i1 %cmp 79} 80 81; Negative test: Wrong predicate 82define i1 @mul_div_cmp_uge(i8 %x) { 83; CHECK-LABEL: @mul_div_cmp_uge( 84; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 3 85; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[MUL]], 4 86; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[DIV]], [[X]] 87; CHECK-NEXT: ret i1 [[CMP]] 88; 89 %mul = mul i8 %x, 3 90 %div = udiv i8 %mul, 4 91 %cmp = icmp uge i8 %div, %x 92 ret i1 %cmp 93} 94 95; Negative test: Wrong predicate 96define i1 @mul_div_cmp_ult(i8 %x) { 97; CHECK-LABEL: @mul_div_cmp_ult( 98; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 3 99; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[MUL]], 4 100; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[DIV]], [[X]] 101; CHECK-NEXT: ret i1 [[CMP]] 102; 103 %mul = mul i8 %x, 3 104 %div = udiv i8 %mul, 4 105 %cmp = icmp ult i8 %div, %x 106 ret i1 %cmp 107} 108 109; Negative test: Wrong icmp operand 110define i1 @mul_div_cmp_wrong_operand(i8 %x, i8 %y) { 111; CHECK-LABEL: @mul_div_cmp_wrong_operand( 112; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 3 113; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[MUL]], 4 114; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[DIV]], [[Y:%.*]] 115; CHECK-NEXT: ret i1 [[CMP]] 116; 117 %mul = mul i8 %x, 3 118 %div = udiv i8 %mul, 4 119 %cmp = icmp ule i8 %div, %y 120 ret i1 %cmp 121} 122 123define i1 @mul_lshr_cmp_smaller(i8 %x) { 124; CHECK-LABEL: @mul_lshr_cmp_smaller( 125; CHECK-NEXT: ret i1 true 126; 127 %mul = mul i8 %x, 3 128 %div = lshr i8 %mul, 2 129 %cmp = icmp ule i8 %div, %x 130 ret i1 %cmp 131} 132 133define i1 @mul_lshr_cmp_equal(i8 %x) { 134; CHECK-LABEL: @mul_lshr_cmp_equal( 135; CHECK-NEXT: ret i1 true 136; 137 %mul = mul i8 %x, 4 138 %div = lshr i8 %mul, 2 139 %cmp = icmp ule i8 %div, %x 140 ret i1 %cmp 141} 142 143define i1 @mul_lshr_cmp_greater(i8 %x) { 144; CHECK-LABEL: @mul_lshr_cmp_greater( 145; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 5 146; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[MUL]], 2 147; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[DIV]], [[X]] 148; CHECK-NEXT: ret i1 [[CMP]] 149; 150 %mul = mul i8 %x, 5 151 %div = lshr i8 %mul, 2 152 %cmp = icmp ule i8 %div, %x 153 ret i1 %cmp 154} 155 156define i1 @shl_div_cmp_smaller(i8 %x) { 157; CHECK-LABEL: @shl_div_cmp_smaller( 158; CHECK-NEXT: ret i1 true 159; 160 %mul = shl i8 %x, 2 161 %div = udiv i8 %mul, 5 162 %cmp = icmp ule i8 %div, %x 163 ret i1 %cmp 164} 165 166define i1 @shl_div_cmp_equal(i8 %x) { 167; CHECK-LABEL: @shl_div_cmp_equal( 168; CHECK-NEXT: ret i1 true 169; 170 %mul = shl i8 %x, 2 171 %div = udiv i8 %mul, 4 172 %cmp = icmp ule i8 %div, %x 173 ret i1 %cmp 174} 175 176define i1 @shl_div_cmp_greater(i8 %x) { 177; CHECK-LABEL: @shl_div_cmp_greater( 178; CHECK-NEXT: [[MUL:%.*]] = shl i8 [[X:%.*]], 2 179; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[MUL]], 3 180; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[DIV]], [[X]] 181; CHECK-NEXT: ret i1 [[CMP]] 182; 183 %mul = shl i8 %x, 2 184 %div = udiv i8 %mul, 3 185 %cmp = icmp ule i8 %div, %x 186 ret i1 %cmp 187} 188 189; Don't crash matching recurrences/invertible ops. 190 191define void @PR50191(i32 %x) { 192; CHECK-LABEL: @PR50191( 193; CHECK-NEXT: entry: 194; CHECK-NEXT: br label [[LOOP:%.*]] 195; CHECK: loop: 196; CHECK-NEXT: [[P1:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[SUB1:%.*]], [[LOOP]] ] 197; CHECK-NEXT: [[P2:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[SUB2:%.*]], [[LOOP]] ] 198; CHECK-NEXT: [[SUB1]] = sub i32 [[P1]], [[P2]] 199; CHECK-NEXT: [[SUB2]] = sub i32 42, [[P2]] 200; CHECK-NEXT: br label [[LOOP]] 201; 202entry: 203 br label %loop 204 205loop: 206 %p1 = phi i32 [ %x, %entry ], [ %sub1, %loop ] 207 %p2 = phi i32 [ %x, %entry ], [ %sub2, %loop ] 208 %cmp = icmp eq i32 %p1, %p2 209 %user = zext i1 %cmp to i32 210 %sub1 = sub i32 %p1, %p2 211 %sub2 = sub i32 42, %p2 212 br label %loop 213} 214 215define i1 @sub_false(i32 %x) { 216; CHECK-LABEL: @sub_false( 217; CHECK-NEXT: ret i1 false 218; 219 %sub = sub i32 1, %x 220 %cmp = icmp eq i32 %sub, %x 221 ret i1 %cmp 222} 223 224define i1 @sub_swap(i8 %x) { 225; CHECK-LABEL: @sub_swap( 226; CHECK-NEXT: ret i1 true 227; 228 %sub = sub i8 3, %x 229 %cmp = icmp ne i8 %x, %sub 230 ret i1 %cmp 231} 232 233define <2 x i1> @sub_odd(<2 x i8> %x) { 234; CHECK-LABEL: @sub_odd( 235; CHECK-NEXT: ret <2 x i1> splat (i1 true) 236; 237 %sub = sub <2 x i8> <i8 3, i8 3>, %x 238 %cmp = icmp ne <2 x i8> %sub, %x 239 ret <2 x i1> %cmp 240} 241 242define <2 x i1> @sub_odd_poison(<2 x i8> %x) { 243; CHECK-LABEL: @sub_odd_poison( 244; CHECK-NEXT: ret <2 x i1> splat (i1 true) 245; 246 %sub = sub <2 x i8> <i8 poison, i8 1>, %x 247 %cmp = icmp ne <2 x i8> %sub, %x 248 ret <2 x i1> %cmp 249} 250 251define i1 @sub_even(i8 %x) { 252; CHECK-LABEL: @sub_even( 253; CHECK-NEXT: [[SUB:%.*]] = sub i8 2, [[X:%.*]] 254; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[SUB]], [[X]] 255; CHECK-NEXT: ret i1 [[CMP]] 256; 257 %sub = sub i8 2, %x 258 %cmp = icmp ne i8 %sub, %x 259 ret i1 %cmp 260} 261 262define i1 @load_ptr(ptr %p) { 263; CHECK-LABEL: @load_ptr( 264; CHECK-NEXT: ret i1 true 265; 266 %load_p = load ptr, ptr %p, !dereferenceable !{i64 8} 267 %r = icmp ne ptr %load_p, null 268 ret i1 %r 269} 270 271define i1 @load_ptr_null_valid(ptr %p) null_pointer_is_valid { 272; CHECK-LABEL: @load_ptr_null_valid( 273; CHECK-NEXT: [[LOAD_P:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable [[META0:![0-9]+]] 274; CHECK-NEXT: [[R:%.*]] = icmp ne ptr [[LOAD_P]], null 275; CHECK-NEXT: ret i1 [[R]] 276; 277 %load_p = load ptr, ptr %p, !dereferenceable !{i64 8} 278 %r = icmp ne ptr %load_p, null 279 ret i1 %r 280} 281 282define i1 @non_eq_disjoint_or_common_op(i8 %x, i8 %y, i8 %ww, i8 %a) { 283; CHECK-LABEL: @non_eq_disjoint_or_common_op( 284; CHECK-NEXT: ret i1 false 285; 286 %w = add nuw i8 %ww, 1 287 %z = add i8 %y, %w 288 289 %xy = or disjoint i8 %x, %y 290 %xz = or disjoint i8 %x, %z 291 292 %axy = add i8 %a, %xy 293 %axz = add i8 %a, %xz 294 %r = icmp eq i8 %axy, %axz 295 ret i1 %r 296} 297 298define i1 @non_eq_disjoint_or_common_op_fail(i8 %x, i8 %y, i8 %ww, i8 %a) { 299; CHECK-LABEL: @non_eq_disjoint_or_common_op_fail( 300; CHECK-NEXT: [[W:%.*]] = add nuw i8 [[WW:%.*]], 1 301; CHECK-NEXT: [[Z:%.*]] = add i8 [[Y:%.*]], [[W]] 302; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y]] 303; CHECK-NEXT: [[XZ:%.*]] = or disjoint i8 [[X]], [[Z]] 304; CHECK-NEXT: [[AXY:%.*]] = add i8 [[A:%.*]], [[XY]] 305; CHECK-NEXT: [[AXZ:%.*]] = add i8 [[A]], [[XZ]] 306; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AXY]], [[AXZ]] 307; CHECK-NEXT: ret i1 [[R]] 308; 309 %w = add nuw i8 %ww, 1 310 %z = add i8 %y, %w 311 312 %xy = or i8 %x, %y 313 %xz = or disjoint i8 %x, %z 314 315 %axy = add i8 %a, %xy 316 %axz = add i8 %a, %xz 317 %r = icmp eq i8 %axy, %axz 318 ret i1 %r 319} 320 321define i1 @non_eq_xor_common_op(i8 %x, i8 %y, i8 %ww, i8 %a) { 322; CHECK-LABEL: @non_eq_xor_common_op( 323; CHECK-NEXT: ret i1 false 324; 325 %w = add nuw i8 %ww, 1 326 %z = add i8 %y, %w 327 328 %xy = xor i8 %y, %x 329 %xz = xor i8 %x, %z 330 331 %axy = add i8 %a, %xy 332 %axz = add i8 %a, %xz 333 %r = icmp eq i8 %axy, %axz 334 ret i1 %r 335} 336 337define i1 @non_eq_xor_common_op_fail(i8 %x, i8 %y, i8 %ww, i8 %a) { 338; CHECK-LABEL: @non_eq_xor_common_op_fail( 339; CHECK-NEXT: [[W:%.*]] = add nsw i8 [[WW:%.*]], 1 340; CHECK-NEXT: [[Z:%.*]] = add i8 [[Y:%.*]], [[W]] 341; CHECK-NEXT: [[XY:%.*]] = xor i8 [[Y]], [[X:%.*]] 342; CHECK-NEXT: [[XZ:%.*]] = xor i8 [[X]], [[Z]] 343; CHECK-NEXT: [[AXY:%.*]] = add i8 [[A:%.*]], [[XY]] 344; CHECK-NEXT: [[AXZ:%.*]] = add i8 [[A]], [[XZ]] 345; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AXY]], [[AXZ]] 346; CHECK-NEXT: ret i1 [[R]] 347; 348 %w = add nsw i8 %ww, 1 349 %z = add i8 %y, %w 350 351 %xy = xor i8 %y, %x 352 %xz = xor i8 %x, %z 353 354 %axy = add i8 %a, %xy 355 %axz = add i8 %a, %xz 356 %r = icmp eq i8 %axy, %axz 357 ret i1 %r 358} 359 360define i1 @non_eq_disjoint_or(i8 %x, i8 %yy, i8 %w) { 361; CHECK-LABEL: @non_eq_disjoint_or( 362; CHECK-NEXT: ret i1 false 363; 364 %y = add nuw i8 %yy, 1 365 %lhs = add i8 %x, %w 366 %val = or disjoint i8 %y, %w 367 %rhs = add i8 %x, %val 368 %r = icmp eq i8 %lhs, %rhs 369 ret i1 %r 370} 371 372define i1 @non_eq_or_fail(i8 %x, i8 %yy, i8 %w) { 373; CHECK-LABEL: @non_eq_or_fail( 374; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 375; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[W:%.*]] 376; CHECK-NEXT: [[VAL:%.*]] = or i8 [[Y]], [[W]] 377; CHECK-NEXT: [[RHS:%.*]] = add i8 [[X]], [[VAL]] 378; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[LHS]], [[RHS]] 379; CHECK-NEXT: ret i1 [[R]] 380; 381 %y = add nuw i8 %yy, 1 382 %lhs = add i8 %x, %w 383 %val = or i8 %y, %w 384 %rhs = add i8 %x, %val 385 %r = icmp eq i8 %lhs, %rhs 386 ret i1 %r 387} 388 389define i1 @non_eq_xor(i8 %x, i8 %yy, i8 %w) { 390; CHECK-LABEL: @non_eq_xor( 391; CHECK-NEXT: ret i1 false 392; 393 %y = add nuw i8 %yy, 1 394 %lhs = add i8 %x, %w 395 %val = xor i8 %y, %w 396 %rhs = add i8 %x, %val 397 %r = icmp eq i8 %lhs, %rhs 398 ret i1 %r 399} 400 401define i1 @non_eq_xor_fail(i8 %x, i8 %yy, i8 %w) { 402; CHECK-LABEL: @non_eq_xor_fail( 403; CHECK-NEXT: [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1 404; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[W:%.*]] 405; CHECK-NEXT: [[VAL:%.*]] = xor i8 [[Y]], [[W]] 406; CHECK-NEXT: [[RHS:%.*]] = add i8 [[X]], [[VAL]] 407; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[LHS]], [[RHS]] 408; CHECK-NEXT: ret i1 [[R]] 409; 410 %y = add nsw i8 %yy, 1 411 %lhs = add i8 %x, %w 412 %val = xor i8 %y, %w 413 %rhs = add i8 %x, %val 414 %r = icmp eq i8 %lhs, %rhs 415 ret i1 %r 416} 417