1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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(i8* %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 i8*> %ptr1vec, i8* %ptr2) { 10; CHECK-LABEL: @bitcast_from_single_element_pointer_vector_to_pointer( 11; CHECK-NEXT: [[PTR1:%.*]] = bitcast <1 x i8*> [[PTR1VEC:%.*]] to i8* 12; CHECK-NEXT: call void @usei8ptr(i8* [[PTR1]]) 13; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[PTR1]], [[PTR2:%.*]] 14; CHECK-NEXT: ret i1 [[CMP]] 15; 16 %ptr1 = bitcast <1 x i8*> %ptr1vec to i8* 17 call void @usei8ptr(i8* %ptr1) 18 %cmp = icmp eq i8* %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