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