1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i32 @sdiv1(i32 %x) { 5; CHECK-LABEL: @sdiv1( 6; CHECK-NEXT: [[Y:%.*]] = sdiv i32 %x, 8 7; CHECK-NEXT: ret i32 [[Y]] 8; 9 %y = sdiv i32 %x, 8 10 ret i32 %y 11} 12 13define i32 @sdiv2(i32 %x) { 14; CHECK-LABEL: @sdiv2( 15; CHECK-NEXT: [[Y:%.*]] = ashr exact i32 %x, 3 16; CHECK-NEXT: ret i32 [[Y]] 17; 18 %y = sdiv exact i32 %x, 8 19 ret i32 %y 20} 21 22define <2 x i32> @sdiv2_vec(<2 x i32> %x) { 23; CHECK-LABEL: @sdiv2_vec( 24; CHECK-NEXT: [[Y:%.*]] = ashr exact <2 x i32> %x, <i32 7, i32 7> 25; CHECK-NEXT: ret <2 x i32> [[Y]] 26; 27 %y = sdiv exact <2 x i32> %x, <i32 128, i32 128> 28 ret <2 x i32> %y 29} 30 31define i32 @sdiv3(i32 %x) { 32; CHECK-LABEL: @sdiv3( 33; CHECK-NEXT: [[Y:%.*]] = srem i32 %x, 3 34; CHECK-NEXT: [[Z:%.*]] = sub i32 %x, [[Y]] 35; CHECK-NEXT: ret i32 [[Z]] 36; 37 %y = sdiv i32 %x, 3 38 %z = mul i32 %y, 3 39 ret i32 %z 40} 41 42define i32 @sdiv4(i32 %x) { 43; CHECK-LABEL: @sdiv4( 44; CHECK-NEXT: ret i32 %x 45; 46 %y = sdiv exact i32 %x, 3 47 %z = mul i32 %y, 3 48 ret i32 %z 49} 50 51define i32 @sdiv5(i32 %x) { 52; CHECK-LABEL: @sdiv5( 53; CHECK-NEXT: [[Y:%.*]] = srem i32 %x, 3 54; CHECK-NEXT: [[Z:%.*]] = sub i32 [[Y]], %x 55; CHECK-NEXT: ret i32 [[Z]] 56; 57 %y = sdiv i32 %x, 3 58 %z = mul i32 %y, -3 59 ret i32 %z 60} 61 62define i32 @sdiv6(i32 %x) { 63; CHECK-LABEL: @sdiv6( 64; CHECK-NEXT: [[Z:%.*]] = sub i32 0, %x 65; CHECK-NEXT: ret i32 [[Z]] 66; 67 %y = sdiv exact i32 %x, 3 68 %z = mul i32 %y, -3 69 ret i32 %z 70} 71 72define i32 @udiv1(i32 %x, i32 %w) { 73; CHECK-LABEL: @udiv1( 74; CHECK-NEXT: ret i32 %x 75; 76 %y = udiv exact i32 %x, %w 77 %z = mul i32 %y, %w 78 ret i32 %z 79} 80 81define i32 @udiv2(i32 %x, i32 %w) { 82; CHECK-LABEL: @udiv2( 83; CHECK-NEXT: [[Z:%.*]] = lshr exact i32 %x, %w 84; CHECK-NEXT: ret i32 [[Z]] 85; 86 %y = shl i32 1, %w 87 %z = udiv exact i32 %x, %y 88 ret i32 %z 89} 90 91define i64 @ashr1(i64 %X) { 92; CHECK-LABEL: @ashr1( 93; CHECK-NEXT: [[A:%.*]] = shl i64 %X, 8 94; CHECK-NEXT: [[B:%.*]] = ashr exact i64 [[A]], 2 95; CHECK-NEXT: ret i64 [[B]] 96; 97 %A = shl i64 %X, 8 98 %B = ashr i64 %A, 2 99 ret i64 %B 100} 101 102; The vector ashr should be exact (like it is in the preceding test). 103 104define <2 x i64> @ashr1_vec(<2 x i64> %X) { 105; CHECK-LABEL: @ashr1_vec( 106; CHECK-NEXT: [[A:%.*]] = shl <2 x i64> %X, <i64 8, i64 8> 107; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i64> [[A]], <i64 2, i64 2> 108; CHECK-NEXT: ret <2 x i64> [[B]] 109; 110 %A = shl <2 x i64> %X, <i64 8, i64 8> 111 %B = ashr <2 x i64> %A, <i64 2, i64 2> 112 ret <2 x i64> %B 113} 114 115; PR9120 116define i1 @ashr_icmp1(i64 %X) { 117; CHECK-LABEL: @ashr_icmp1( 118; CHECK-NEXT: [[B:%.*]] = icmp eq i64 %X, 0 119; CHECK-NEXT: ret i1 [[B]] 120; 121 %A = ashr exact i64 %X, 2 ; X/4 122 %B = icmp eq i64 %A, 0 123 ret i1 %B 124} 125 126define i1 @ashr_icmp2(i64 %X) { 127; CHECK-LABEL: @ashr_icmp2( 128; CHECK-NEXT: [[Z:%.*]] = icmp slt i64 %X, 16 129; CHECK-NEXT: ret i1 [[Z]] 130; 131 %Y = ashr exact i64 %X, 2 ; x / 4 132 %Z = icmp slt i64 %Y, 4 ; x < 16 133 ret i1 %Z 134} 135 136define <2 x i1> @ashr_icmp2_vec(<2 x i64> %X) { 137; CHECK-LABEL: @ashr_icmp2_vec( 138; CHECK-NEXT: [[Z:%.*]] = icmp slt <2 x i64> %X, <i64 16, i64 16> 139; CHECK-NEXT: ret <2 x i1> [[Z]] 140; 141 %Y = ashr exact <2 x i64> %X, <i64 2, i64 2> 142 %Z = icmp slt <2 x i64> %Y, <i64 4, i64 4> 143 ret <2 x i1> %Z 144} 145 146; PR9998 147; Make sure we don't transform the ashr here into an sdiv 148define i1 @pr9998(i32 %V) { 149; CHECK-LABEL: @pr9998( 150; CHECK-NEXT: [[W_MASK:%.*]] = and i32 %V, 1 151; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[W_MASK]], 0 152; CHECK-NEXT: ret i1 [[Z]] 153; 154 %W = shl i32 %V, 31 155 %X = ashr exact i32 %W, 31 156 %Y = sext i32 %X to i64 157 %Z = icmp ugt i64 %Y, 7297771788697658747 158 ret i1 %Z 159} 160 161; FIXME: Vectors should fold the same way. 162define <2 x i1> @pr9998vec(<2 x i32> %V) { 163; CHECK-LABEL: @pr9998vec( 164; CHECK-NEXT: [[W:%.*]] = shl <2 x i32> %V, <i32 31, i32 31> 165; CHECK-NEXT: [[X:%.*]] = ashr exact <2 x i32> [[W]], <i32 31, i32 31> 166; CHECK-NEXT: [[Y:%.*]] = sext <2 x i32> [[X]] to <2 x i64> 167; CHECK-NEXT: [[Z:%.*]] = icmp ugt <2 x i64> [[Y]], <i64 7297771788697658747, i64 7297771788697658747> 168; CHECK-NEXT: ret <2 x i1> [[Z]] 169; 170 %W = shl <2 x i32> %V, <i32 31, i32 31> 171 %X = ashr exact <2 x i32> %W, <i32 31, i32 31> 172 %Y = sext <2 x i32> %X to <2 x i64> 173 %Z = icmp ugt <2 x i64> %Y, <i64 7297771788697658747, i64 7297771788697658747> 174 ret <2 x i1> %Z 175} 176 177define i1 @udiv_icmp1(i64 %X) { 178; CHECK-LABEL: @udiv_icmp1( 179; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 %X, 0 180; CHECK-NEXT: ret i1 [[TMP1]] 181; 182 %A = udiv exact i64 %X, 5 ; X/5 183 %B = icmp ne i64 %A, 0 184 ret i1 %B 185} 186 187define <2 x i1> @udiv_icmp1_vec(<2 x i64> %X) { 188; CHECK-LABEL: @udiv_icmp1_vec( 189; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> %X, zeroinitializer 190; CHECK-NEXT: ret <2 x i1> [[TMP1]] 191; 192 %A = udiv exact <2 x i64> %X, <i64 5, i64 5> 193 %B = icmp ne <2 x i64> %A, zeroinitializer 194 ret <2 x i1> %B 195} 196 197define i1 @udiv_icmp2(i64 %X) { 198; CHECK-LABEL: @udiv_icmp2( 199; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 200; CHECK-NEXT: ret i1 [[TMP1]] 201; 202 %A = udiv exact i64 %X, 5 ; X/5 == 0 --> x == 0 203 %B = icmp eq i64 %A, 0 204 ret i1 %B 205} 206 207define <2 x i1> @udiv_icmp2_vec(<2 x i64> %X) { 208; CHECK-LABEL: @udiv_icmp2_vec( 209; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer 210; CHECK-NEXT: ret <2 x i1> [[TMP1]] 211; 212 %A = udiv exact <2 x i64> %X, <i64 5, i64 5> 213 %B = icmp eq <2 x i64> %A, zeroinitializer 214 ret <2 x i1> %B 215} 216 217define i1 @sdiv_icmp1(i64 %X) { 218; CHECK-LABEL: @sdiv_icmp1( 219; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 220; CHECK-NEXT: ret i1 [[TMP1]] 221; 222 %A = sdiv exact i64 %X, 5 ; X/5 == 0 --> x == 0 223 %B = icmp eq i64 %A, 0 224 ret i1 %B 225} 226 227define <2 x i1> @sdiv_icmp1_vec(<2 x i64> %X) { 228; CHECK-LABEL: @sdiv_icmp1_vec( 229; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer 230; CHECK-NEXT: ret <2 x i1> [[TMP1]] 231; 232 %A = sdiv exact <2 x i64> %X, <i64 5, i64 5> 233 %B = icmp eq <2 x i64> %A, zeroinitializer 234 ret <2 x i1> %B 235} 236 237define i1 @sdiv_icmp2(i64 %X) { 238; CHECK-LABEL: @sdiv_icmp2( 239; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 5 240; CHECK-NEXT: ret i1 [[TMP1]] 241; 242 %A = sdiv exact i64 %X, 5 ; X/5 == 1 --> x == 5 243 %B = icmp eq i64 %A, 1 244 ret i1 %B 245} 246 247define <2 x i1> @sdiv_icmp2_vec(<2 x i64> %X) { 248; CHECK-LABEL: @sdiv_icmp2_vec( 249; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, <i64 5, i64 5> 250; CHECK-NEXT: ret <2 x i1> [[TMP1]] 251; 252 %A = sdiv exact <2 x i64> %X, <i64 5, i64 5> 253 %B = icmp eq <2 x i64> %A, <i64 1, i64 1> 254 ret <2 x i1> %B 255} 256 257define i1 @sdiv_icmp3(i64 %X) { 258; CHECK-LABEL: @sdiv_icmp3( 259; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, -5 260; CHECK-NEXT: ret i1 [[TMP1]] 261; 262 %A = sdiv exact i64 %X, 5 ; X/5 == -1 --> x == -5 263 %B = icmp eq i64 %A, -1 264 ret i1 %B 265} 266 267define <2 x i1> @sdiv_icmp3_vec(<2 x i64> %X) { 268; CHECK-LABEL: @sdiv_icmp3_vec( 269; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, <i64 -5, i64 -5> 270; CHECK-NEXT: ret <2 x i1> [[TMP1]] 271; 272 %A = sdiv exact <2 x i64> %X, <i64 5, i64 5> 273 %B = icmp eq <2 x i64> %A, <i64 -1, i64 -1> 274 ret <2 x i1> %B 275} 276 277define i1 @sdiv_icmp4(i64 %X) { 278; CHECK-LABEL: @sdiv_icmp4( 279; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 280; CHECK-NEXT: ret i1 [[TMP1]] 281; 282 %A = sdiv exact i64 %X, -5 ; X/-5 == 0 --> x == 0 283 %B = icmp eq i64 %A, 0 284 ret i1 %B 285} 286 287define <2 x i1> @sdiv_icmp4_vec(<2 x i64> %X) { 288; CHECK-LABEL: @sdiv_icmp4_vec( 289; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer 290; CHECK-NEXT: ret <2 x i1> [[TMP1]] 291; 292 %A = sdiv exact <2 x i64> %X, <i64 -5, i64 -5> 293 %B = icmp eq <2 x i64> %A, zeroinitializer 294 ret <2 x i1> %B 295} 296 297define i1 @sdiv_icmp5(i64 %X) { 298; CHECK-LABEL: @sdiv_icmp5( 299; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, -5 300; CHECK-NEXT: ret i1 [[TMP1]] 301; 302 %A = sdiv exact i64 %X, -5 ; X/-5 == 1 --> x == -5 303 %B = icmp eq i64 %A, 1 304 ret i1 %B 305} 306 307define <2 x i1> @sdiv_icmp5_vec(<2 x i64> %X) { 308; CHECK-LABEL: @sdiv_icmp5_vec( 309; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, <i64 -5, i64 -5> 310; CHECK-NEXT: ret <2 x i1> [[TMP1]] 311; 312 %A = sdiv exact <2 x i64> %X, <i64 -5, i64 -5> 313 %B = icmp eq <2 x i64> %A, <i64 1, i64 1> 314 ret <2 x i1> %B 315} 316 317define i1 @sdiv_icmp6(i64 %X) { 318; CHECK-LABEL: @sdiv_icmp6( 319; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 5 320; CHECK-NEXT: ret i1 [[TMP1]] 321; 322 %A = sdiv exact i64 %X, -5 ; X/-5 == -1 --> x == 5 323 %B = icmp eq i64 %A, -1 324 ret i1 %B 325} 326 327define <2 x i1> @sdiv_icmp6_vec(<2 x i64> %X) { 328; CHECK-LABEL: @sdiv_icmp6_vec( 329; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, <i64 5, i64 5> 330; CHECK-NEXT: ret <2 x i1> [[TMP1]] 331; 332 %A = sdiv exact <2 x i64> %X, <i64 -5, i64 -5> 333 %B = icmp eq <2 x i64> %A, <i64 -1, i64 -1> 334 ret <2 x i1> %B 335} 336 337