1; NOTE: Assertions have been autogenerated by update_test_checks.py 2; RUN: opt -S %s -instsimplify | FileCheck %s 3 4; A ==> A -> true 5define i1 @test(i32 %length.i, i32 %i) { 6; CHECK-LABEL: @test( 7; CHECK: ret i1 true 8; 9 %var29 = icmp slt i32 %i, %length.i 10 %res = icmp uge i1 %var29, %var29 11 ret i1 %res 12} 13 14; i +_{nsw} C_{>0} <s L ==> i <s L -> true 15define i1 @test2(i32 %length.i, i32 %i) { 16; CHECK-LABEL: @test2( 17; CHECK: ret i1 true 18; 19 %iplus1 = add nsw i32 %i, 1 20 %var29 = icmp slt i32 %i, %length.i 21 %var30 = icmp slt i32 %iplus1, %length.i 22 %res = icmp ule i1 %var30, %var29 23 ret i1 %res 24} 25 26; i + C_{>0} <s L ==> i <s L -> unknown without the nsw 27define i1 @test2_neg(i32 %length.i, i32 %i) { 28; CHECK-LABEL: @test2_neg( 29; CHECK: [[IPLUS1:%.*]] = add i32 %i, 1 30; CHECK-NEXT: [[VAR29:%.*]] = icmp slt i32 %i, %length.i 31; CHECK-NEXT: [[VAR30:%.*]] = icmp slt i32 [[IPLUS1]], %length.i 32; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[VAR30]], [[VAR29]] 33; CHECK-NEXT: ret i1 [[RES]] 34; 35 %iplus1 = add i32 %i, 1 36 %var29 = icmp slt i32 %i, %length.i 37 %var30 = icmp slt i32 %iplus1, %length.i 38 %res = icmp ule i1 %var30, %var29 39 ret i1 %res 40} 41 42; sle is not implication 43define i1 @test2_neg2(i32 %length.i, i32 %i) { 44; CHECK-LABEL: @test2_neg2( 45; CHECK: [[IPLUS1:%.*]] = add i32 %i, 1 46; CHECK-NEXT: [[VAR29:%.*]] = icmp slt i32 %i, %length.i 47; CHECK-NEXT: [[VAR30:%.*]] = icmp slt i32 [[IPLUS1]], %length.i 48; CHECK-NEXT: [[RES:%.*]] = icmp sle i1 [[VAR30]], [[VAR29]] 49; CHECK-NEXT: ret i1 [[RES]] 50; 51 %iplus1 = add i32 %i, 1 52 %var29 = icmp slt i32 %i, %length.i 53 %var30 = icmp slt i32 %iplus1, %length.i 54 %res = icmp sle i1 %var30, %var29 55 ret i1 %res 56} 57 58; The binary operator has to be an add 59define i1 @test2_neg3(i32 %length.i, i32 %i) { 60; CHECK-LABEL: @test2_neg3( 61; CHECK: [[IPLUS1:%.*]] = sub nsw i32 %i, 1 62; CHECK-NEXT: [[VAR29:%.*]] = icmp slt i32 %i, %length.i 63; CHECK-NEXT: [[VAR30:%.*]] = icmp slt i32 [[IPLUS1]], %length.i 64; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[VAR30]], [[VAR29]] 65; CHECK-NEXT: ret i1 [[RES]] 66; 67 %iplus1 = sub nsw i32 %i, 1 68 %var29 = icmp slt i32 %i, %length.i 69 %var30 = icmp slt i32 %iplus1, %length.i 70 %res = icmp ule i1 %var30, %var29 71 ret i1 %res 72} 73 74; i +_{nsw} C_{>0} <s L ==> i <s L -> true 75; With an inverted conditional (ule B A rather than canonical ugt A B 76define i1 @test3(i32 %length.i, i32 %i) { 77; CHECK-LABEL: @test3( 78; CHECK: ret i1 true 79; 80 %iplus1 = add nsw i32 %i, 1 81 %var29 = icmp slt i32 %i, %length.i 82 %var30 = icmp slt i32 %iplus1, %length.i 83 %res = icmp uge i1 %var29, %var30 84 ret i1 %res 85} 86 87; i +_{nuw} C <u L ==> i <u L 88define i1 @test4(i32 %length.i, i32 %i) { 89; CHECK-LABEL: @test4( 90; CHECK: ret i1 true 91; 92 %iplus1 = add nuw i32 %i, 1 93 %var29 = icmp ult i32 %i, %length.i 94 %var30 = icmp ult i32 %iplus1, %length.i 95 %res = icmp ule i1 %var30, %var29 96 ret i1 %res 97} 98 99; A ==> A for vectors 100define <4 x i1> @test5(<4 x i1> %vec) { 101; CHECK-LABEL: @test5( 102; CHECK: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true> 103; 104 %res = icmp ule <4 x i1> %vec, %vec 105 ret <4 x i1> %res 106} 107 108; Don't crash on vector inputs - pr25040 109define <4 x i1> @test6(<4 x i1> %a, <4 x i1> %b) { 110; CHECK-LABEL: @test6( 111; CHECK: [[RES:%.*]] = icmp ule <4 x i1> %a, %b 112; CHECK-NEXT: ret <4 x i1> [[RES]] 113; 114 %res = icmp ule <4 x i1> %a, %b 115 ret <4 x i1> %res 116} 117 118; i +_{nsw} 1 <s L ==> i < L +_{nsw} 1 119define i1 @test7(i32 %length.i, i32 %i) { 120; CHECK-LABEL: @test7( 121; CHECK: ret i1 true 122; 123 %iplus1 = add nsw i32 %i, 1 124 %len.plus.one = add nsw i32 %length.i, 1 125 %var29 = icmp slt i32 %i, %len.plus.one 126 %var30 = icmp slt i32 %iplus1, %length.i 127 %res = icmp ule i1 %var30, %var29 128 ret i1 %res 129} 130 131; i +_{nuw} 1 <u L ==> i < L +_{nuw} 1 132define i1 @test8(i32 %length.i, i32 %i) { 133; CHECK-LABEL: @test8( 134; CHECK: ret i1 true 135; 136 %iplus1 = add nuw i32 %i, 1 137 %len.plus.one = add nuw i32 %length.i, 1 138 %var29 = icmp ult i32 %i, %len.plus.one 139 %var30 = icmp ult i32 %iplus1, %length.i 140 %res = icmp ule i1 %var30, %var29 141 ret i1 %res 142} 143 144; i +_{nuw} C <u L ==> i < L, even if C is negative 145define i1 @test9(i32 %length.i, i32 %i) { 146; CHECK-LABEL: @test9( 147; CHECK: ret i1 true 148; 149 %iplus1 = add nuw i32 %i, -100 150 %var29 = icmp ult i32 %i, %length.i 151 %var30 = icmp ult i32 %iplus1, %length.i 152 %res = icmp ule i1 %var30, %var29 153 ret i1 %res 154} 155 156define i1 @test10(i32 %length.i, i32 %x.full) { 157; CHECK-LABEL: @test10( 158; CHECK: ret i1 true 159; 160 %x = and i32 %x.full, 4294901760 ;; 4294901760 == 0xffff0000 161 %large = or i32 %x, 100 162 %small = or i32 %x, 90 163 %known = icmp ult i32 %large, %length.i 164 %to.prove = icmp ult i32 %small, %length.i 165 %res = icmp ule i1 %known, %to.prove 166 ret i1 %res 167} 168 169define i1 @test11(i32 %length.i, i32 %x) { 170; CHECK-LABEL: @test11( 171; CHECK: [[LARGE:%.*]] = or i32 %x, 100 172; CHECK-NEXT: [[SMALL:%.*]] = or i32 %x, 90 173; CHECK-NEXT: [[KNOWN:%.*]] = icmp ult i32 [[LARGE]], %length.i 174; CHECK-NEXT: [[TO_PROVE:%.*]] = icmp ult i32 [[SMALL]], %length.i 175; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[KNOWN]], [[TO_PROVE]] 176; CHECK-NEXT: ret i1 [[RES]] 177; 178 %large = or i32 %x, 100 179 %small = or i32 %x, 90 180 %known = icmp ult i32 %large, %length.i 181 %to.prove = icmp ult i32 %small, %length.i 182 %res = icmp ule i1 %known, %to.prove 183 ret i1 %res 184} 185 186define i1 @test12(i32 %length.i, i32 %x.full) { 187; CHECK-LABEL: @test12( 188; CHECK: [[X:%.*]] = and i32 [[X:%.*]].full, -65536 189; CHECK-NEXT: [[LARGE:%.*]] = or i32 [[X]], 65536 190; CHECK-NEXT: [[SMALL:%.*]] = or i32 [[X]], 90 191; CHECK-NEXT: [[KNOWN:%.*]] = icmp ult i32 [[LARGE]], %length.i 192; CHECK-NEXT: [[TO_PROVE:%.*]] = icmp ult i32 [[SMALL]], %length.i 193; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[KNOWN]], [[TO_PROVE]] 194; CHECK-NEXT: ret i1 [[RES]] 195; 196 %x = and i32 %x.full, 4294901760 ;; 4294901760 == 0xffff0000 197 %large = or i32 %x, 65536 ;; 65536 == 0x00010000 198 %small = or i32 %x, 90 199 %known = icmp ult i32 %large, %length.i 200 %to.prove = icmp ult i32 %small, %length.i 201 %res = icmp ule i1 %known, %to.prove 202 ret i1 %res 203} 204 205define i1 @test13(i32 %length.i, i32 %x) { 206; CHECK-LABEL: @test13( 207; CHECK: ret i1 true 208; 209 %large = add nuw i32 %x, 100 210 %small = add nuw i32 %x, 90 211 %known = icmp ult i32 %large, %length.i 212 %to.prove = icmp ult i32 %small, %length.i 213 %res = icmp ule i1 %known, %to.prove 214 ret i1 %res 215} 216 217define i1 @test14(i32 %length.i, i32 %x.full) { 218; CHECK-LABEL: @test14( 219; CHECK: ret i1 true 220; 221 %x = and i32 %x.full, 4294905615 ;; 4294905615 == 0xffff0f0f 222 %large = or i32 %x, 8224 ;; == 0x2020 223 %small = or i32 %x, 4112 ;; == 0x1010 224 %known = icmp ult i32 %large, %length.i 225 %to.prove = icmp ult i32 %small, %length.i 226 %res = icmp ule i1 %known, %to.prove 227 ret i1 %res 228} 229 230define i1 @test15(i32 %length.i, i32 %x) { 231; CHECK-LABEL: @test15( 232; CHECK: [[LARGE:%.*]] = add nuw i32 %x, 100 233; CHECK-NEXT: [[SMALL:%.*]] = add nuw i32 %x, 110 234; CHECK-NEXT: [[KNOWN:%.*]] = icmp ult i32 [[LARGE]], %length.i 235; CHECK-NEXT: [[TO_PROVE:%.*]] = icmp ult i32 [[SMALL]], %length.i 236; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[KNOWN]], [[TO_PROVE]] 237; CHECK-NEXT: ret i1 [[RES]] 238; 239 %large = add nuw i32 %x, 100 240 %small = add nuw i32 %x, 110 241 %known = icmp ult i32 %large, %length.i 242 %to.prove = icmp ult i32 %small, %length.i 243 %res = icmp ule i1 %known, %to.prove 244 ret i1 %res 245} 246 247; X >=(s) Y == X ==> Y (i1 1 becomes -1 for reasoning) 248define i1 @test_sge(i32 %length.i, i32 %i) { 249; CHECK-LABEL: @test_sge( 250; CHECK: ret i1 true 251; 252 %iplus1 = add nsw nuw i32 %i, 1 253 %var29 = icmp ult i32 %i, %length.i 254 %var30 = icmp ult i32 %iplus1, %length.i 255 %res = icmp sge i1 %var30, %var29 256 ret i1 %res 257} 258