1; This test makes sure that div instructions are properly eliminated. 2 3; RUN: opt < %s -instcombine -S | FileCheck %s 4 5define i32 @test1(i32 %A) { 6 %B = sdiv i32 %A, 1 ; <i32> [#uses=1] 7 ret i32 %B 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: ret i32 %A 10} 11 12define i32 @test2(i32 %A) { 13 ; => Shift 14 %B = udiv i32 %A, 8 ; <i32> [#uses=1] 15 ret i32 %B 16; CHECK-LABEL: @test2( 17; CHECK-NEXT: lshr i32 %A, 3 18} 19 20define i32 @test3(i32 %A) { 21 ; => 0, don't need to keep traps 22 %B = sdiv i32 0, %A ; <i32> [#uses=1] 23 ret i32 %B 24; CHECK-LABEL: @test3( 25; CHECK-NEXT: ret i32 0 26} 27 28define i32 @test4(i32 %A) { 29 ; 0-A 30 %B = sdiv i32 %A, -1 ; <i32> [#uses=1] 31 ret i32 %B 32; CHECK-LABEL: @test4( 33; CHECK-NEXT: sub i32 0, %A 34} 35 36define i32 @test5(i32 %A) { 37 %B = udiv i32 %A, -16 ; <i32> [#uses=1] 38 %C = udiv i32 %B, -4 ; <i32> [#uses=1] 39 ret i32 %C 40; CHECK-LABEL: @test5( 41; CHECK-NEXT: ret i32 0 42} 43 44define i1 @test6(i32 %A) { 45 %B = udiv i32 %A, 123 ; <i32> [#uses=1] 46 ; A < 123 47 %C = icmp eq i32 %B, 0 ; <i1> [#uses=1] 48 ret i1 %C 49; CHECK-LABEL: @test6( 50; CHECK-NEXT: icmp ult i32 %A, 123 51} 52 53define i1 @test7(i32 %A) { 54 %B = udiv i32 %A, 10 ; <i32> [#uses=1] 55 ; A >= 20 && A < 30 56 %C = icmp eq i32 %B, 2 ; <i1> [#uses=1] 57 ret i1 %C 58; CHECK-LABEL: @test7( 59; CHECK-NEXT: add i32 %A, -20 60; CHECK-NEXT: icmp ult i32 61} 62 63define i1 @test8(i8 %A) { 64 %B = udiv i8 %A, 123 ; <i8> [#uses=1] 65 ; A >= 246 66 %C = icmp eq i8 %B, 2 ; <i1> [#uses=1] 67 ret i1 %C 68; CHECK-LABEL: @test8( 69; CHECK-NEXT: icmp ugt i8 %A, -11 70} 71 72define i1 @test9(i8 %A) { 73 %B = udiv i8 %A, 123 ; <i8> [#uses=1] 74 ; A < 246 75 %C = icmp ne i8 %B, 2 ; <i1> [#uses=1] 76 ret i1 %C 77; CHECK-LABEL: @test9( 78; CHECK-NEXT: icmp ult i8 %A, -10 79} 80 81define i32 @test10(i32 %X, i1 %C) { 82 %V = select i1 %C, i32 64, i32 8 ; <i32> [#uses=1] 83 %R = udiv i32 %X, %V ; <i32> [#uses=1] 84 ret i32 %R 85; CHECK-LABEL: @test10( 86; CHECK-NEXT: select i1 %C, i32 6, i32 3 87; CHECK-NEXT: lshr i32 %X 88} 89 90define i32 @test11(i32 %X, i1 %C) { 91 %A = select i1 %C, i32 1024, i32 32 ; <i32> [#uses=1] 92 %B = udiv i32 %X, %A ; <i32> [#uses=1] 93 ret i32 %B 94; CHECK-LABEL: @test11( 95; CHECK-NEXT: select i1 %C, i32 10, i32 5 96; CHECK-NEXT: lshr i32 %X 97} 98 99; PR2328 100define i32 @test12(i32 %x) nounwind { 101 %tmp3 = udiv i32 %x, %x ; 1 102 ret i32 %tmp3 103; CHECK-LABEL: @test12( 104; CHECK-NEXT: ret i32 1 105} 106 107define i32 @test13(i32 %x) nounwind { 108 %tmp3 = sdiv i32 %x, %x ; 1 109 ret i32 %tmp3 110; CHECK-LABEL: @test13( 111; CHECK-NEXT: ret i32 1 112} 113 114define i32 @test14(i8 %x) nounwind { 115 %zext = zext i8 %x to i32 116 %div = udiv i32 %zext, 257 ; 0 117 ret i32 %div 118; CHECK-LABEL: @test14( 119; CHECK-NEXT: ret i32 0 120} 121 122; PR9814 123define i32 @test15(i32 %a, i32 %b) nounwind { 124 %shl = shl i32 1, %b 125 %div = lshr i32 %shl, 2 126 %div2 = udiv i32 %a, %div 127 ret i32 %div2 128; CHECK-LABEL: @test15( 129; CHECK-NEXT: add i32 %b, -2 130; CHECK-NEXT: lshr i32 %a, 131; CHECK-NEXT: ret i32 132} 133 134define <2 x i64> @test16(<2 x i64> %x) nounwind { 135 %shr = lshr <2 x i64> %x, <i64 5, i64 5> 136 %div = udiv <2 x i64> %shr, <i64 6, i64 6> 137 ret <2 x i64> %div 138; CHECK-LABEL: @test16( 139; CHECK-NEXT: udiv <2 x i64> %x, <i64 192, i64 192> 140; CHECK-NEXT: ret <2 x i64> 141} 142 143define <2 x i64> @test17(<2 x i64> %x) nounwind { 144 %neg = sub nsw <2 x i64> zeroinitializer, %x 145 %div = sdiv <2 x i64> %neg, <i64 3, i64 4> 146 ret <2 x i64> %div 147; CHECK-LABEL: @test17( 148; CHECK-NEXT: sdiv <2 x i64> %x, <i64 -3, i64 -4> 149; CHECK-NEXT: ret <2 x i64> 150} 151 152define <2 x i64> @test18(<2 x i64> %x) nounwind { 153 %div = sdiv <2 x i64> %x, <i64 -1, i64 -1> 154 ret <2 x i64> %div 155; CHECK-LABEL: @test18( 156; CHECK-NEXT: sub <2 x i64> zeroinitializer, %x 157; CHECK-NEXT: ret <2 x i64> 158} 159 160define i32 @test19(i32 %x) { 161 %A = udiv i32 1, %x 162 ret i32 %A 163; CHECK-LABEL: @test19( 164; CHECK-NEXT: icmp eq i32 %x, 1 165; CHECK-NEXT: zext i1 %{{.*}} to i32 166; CHECK-NEXT: ret i32 167} 168 169define i32 @test20(i32 %x) { 170 %A = sdiv i32 1, %x 171 ret i32 %A 172; CHECK-LABEL: @test20( 173; CHECK-NEXT: add i32 %x, 1 174; CHECK-NEXT: icmp ult i32 %{{.*}}, 3 175; CHECK-NEXT: select i1 %{{.*}}, i32 %x, i32 {{.*}} 176; CHECK-NEXT: ret i32 177} 178 179define i32 @test21(i32 %a) { 180 %shl = shl nsw i32 %a, 2 181 %div = sdiv i32 %shl, 12 182 ret i32 %div 183; CHECK-LABEL: @test21( 184; CHECK-NEXT: %div = sdiv i32 %a, 3 185; CHECK-NEXT: ret i32 %div 186} 187 188define i32 @test22(i32 %a) { 189 %mul = mul nsw i32 %a, 3 190 %div = sdiv i32 %mul, 12 191 ret i32 %div 192; CHECK-LABEL: @test22( 193; CHECK-NEXT: %div = sdiv i32 %a, 4 194; CHECK-NEXT: ret i32 %div 195} 196 197define i32 @test23(i32 %a) { 198 %shl = shl nuw i32 %a, 2 199 %div = udiv i32 %shl, 12 200 ret i32 %div 201; CHECK-LABEL: @test23( 202; CHECK-NEXT: %div = udiv i32 %a, 3 203; CHECK-NEXT: ret i32 %div 204} 205 206define i32 @test24(i32 %a) { 207 %mul = mul nuw i32 %a, 3 208 %div = udiv i32 %mul, 12 209 ret i32 %div 210; CHECK-LABEL: @test24( 211; CHECK-NEXT: %div = lshr i32 %a, 2 212; CHECK-NEXT: ret i32 %div 213} 214 215define i32 @test25(i32 %a) { 216 %shl = shl nsw i32 %a, 2 217 %div = sdiv i32 %shl, 2 218 ret i32 %div 219; CHECK-LABEL: @test25( 220; CHECK-NEXT: %div = shl nsw i32 %a, 1 221; CHECK-NEXT: ret i32 %div 222} 223 224define i32 @test26(i32 %a) { 225 %mul = mul nsw i32 %a, 12 226 %div = sdiv i32 %mul, 3 227 ret i32 %div 228; CHECK-LABEL: @test26( 229; CHECK-NEXT: %div = shl nsw i32 %a, 2 230; CHECK-NEXT: ret i32 %div 231} 232 233define i32 @test27(i32 %a) { 234 %shl = shl nuw i32 %a, 2 235 %div = udiv i32 %shl, 2 236 ret i32 %div 237; CHECK-LABEL: @test27( 238; CHECK-NEXT: %div = shl nuw i32 %a, 1 239; CHECK-NEXT: ret i32 %div 240} 241 242define i32 @test28(i32 %a) { 243 %mul = mul nuw i32 %a, 36 244 %div = udiv i32 %mul, 3 245 ret i32 %div 246; CHECK-LABEL: @test28( 247; CHECK-NEXT: %div = mul nuw i32 %a, 12 248; CHECK-NEXT: ret i32 %div 249} 250 251define i32 @test29(i32 %a) { 252 %mul = shl nsw i32 %a, 31 253 %div = sdiv i32 %mul, -2147483648 254 ret i32 %div 255; CHECK-LABEL: @test29( 256; CHECK-NEXT: %[[and:.*]] = and i32 %a, 1 257; CHECK-NEXT: ret i32 %[[and]] 258} 259 260define i32 @test30(i32 %a) { 261 %mul = shl nuw i32 %a, 31 262 %div = udiv i32 %mul, -2147483648 263 ret i32 %div 264; CHECK-LABEL: @test30( 265; CHECK-NEXT: ret i32 %a 266} 267 268define <2 x i32> @test31(<2 x i32> %x) { 269 %shr = lshr <2 x i32> %x, <i32 31, i32 31> 270 %div = udiv <2 x i32> %shr, <i32 2147483647, i32 2147483647> 271 ret <2 x i32> %div 272; CHECK-LABEL: @test31( 273; CHECK-NEXT: ret <2 x i32> zeroinitializer 274} 275 276define i32 @test32(i32 %a, i32 %b) { 277 %shl = shl i32 2, %b 278 %div = lshr i32 %shl, 2 279 %div2 = udiv i32 %a, %div 280 ret i32 %div2 281; CHECK-LABEL: @test32( 282; CHECK-NEXT: %[[shl:.*]] = shl i32 2, %b 283; CHECK-NEXT: %[[shr:.*]] = lshr i32 %[[shl]], 2 284; CHECK-NEXT: %[[div:.*]] = udiv i32 %a, %[[shr]] 285; CHECK-NEXT: ret i32 286} 287 288define <2 x i64> @test33(<2 x i64> %x) nounwind { 289 %shr = lshr exact <2 x i64> %x, <i64 5, i64 5> 290 %div = udiv exact <2 x i64> %shr, <i64 6, i64 6> 291 ret <2 x i64> %div 292; CHECK-LABEL: @test33( 293; CHECK-NEXT: udiv exact <2 x i64> %x, <i64 192, i64 192> 294; CHECK-NEXT: ret <2 x i64> 295} 296 297define <2 x i64> @test34(<2 x i64> %x) nounwind { 298 %neg = sub nsw <2 x i64> zeroinitializer, %x 299 %div = sdiv exact <2 x i64> %neg, <i64 3, i64 4> 300 ret <2 x i64> %div 301; CHECK-LABEL: @test34( 302; CHECK-NEXT: sdiv exact <2 x i64> %x, <i64 -3, i64 -4> 303; CHECK-NEXT: ret <2 x i64> 304} 305 306define i32 @test35(i32 %A) { 307 %and = and i32 %A, 2147483647 308 %mul = sdiv exact i32 %and, 2147483647 309 ret i32 %mul 310; CHECK-LABEL: @test35( 311; CHECK-NEXT: %[[and:.*]] = and i32 %A, 2147483647 312; CHECK-NEXT: %[[udiv:.*]] = udiv exact i32 %[[and]], 2147483647 313; CHECK-NEXT: ret i32 %[[udiv]] 314} 315 316define i32 @test36(i32 %A) { 317 %and = and i32 %A, 2147483647 318 %shl = shl nsw i32 1, %A 319 %mul = sdiv exact i32 %and, %shl 320 ret i32 %mul 321; CHECK-LABEL: @test36( 322; CHECK-NEXT: %[[and:.*]] = and i32 %A, 2147483647 323; CHECK-NEXT: %[[shr:.*]] = lshr exact i32 %[[and]], %A 324; CHECK-NEXT: ret i32 %[[shr]] 325} 326 327define i32 @test37(i32* %b) { 328entry: 329 store i32 0, i32* %b, align 4 330 %0 = load i32, i32* %b, align 4 331 br i1 undef, label %lor.rhs, label %lor.end 332 333lor.rhs: ; preds = %entry 334 %mul = mul nsw i32 undef, %0 335 br label %lor.end 336 337lor.end: ; preds = %lor.rhs, %entry 338 %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ] 339 %div = sdiv i32 %t.0, 2 340 ret i32 %div 341; CHECK-LABEL: @test37( 342; CHECK: ret i32 0 343} 344