1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(i8) 5 6declare i8 @llvm.umin.i8(i8, i8) 7declare i8 @llvm.umax.i8(i8, i8) 8declare i8 @llvm.smin.i8(i8, i8) 9declare i8 @llvm.smax.i8(i8, i8) 10 11define i32 @t1(i16 zeroext %x, i32 %y) { 12; CHECK-LABEL: @t1( 13; CHECK-NEXT: entry: 14; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32 15; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[Y:%.*]], 1 16; CHECK-NEXT: [[D1:%.*]] = lshr i32 [[CONV]], [[TMP0]] 17; CHECK-NEXT: ret i32 [[D1]] 18; 19entry: 20 %conv = zext i16 %x to i32 21 %s = shl i32 2, %y 22 %d = sdiv i32 %conv, %s 23 ret i32 %d 24} 25 26define <2 x i32> @t1vec(<2 x i16> %x, <2 x i32> %y) { 27; CHECK-LABEL: @t1vec( 28; CHECK-NEXT: entry: 29; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32> 30; CHECK-NEXT: [[TMP0:%.*]] = add <2 x i32> [[Y:%.*]], <i32 1, i32 1> 31; CHECK-NEXT: [[D1:%.*]] = lshr <2 x i32> [[CONV]], [[TMP0]] 32; CHECK-NEXT: ret <2 x i32> [[D1]] 33; 34entry: 35 %conv = zext <2 x i16> %x to <2 x i32> 36 %s = shl <2 x i32> <i32 2, i32 2>, %y 37 %d = sdiv <2 x i32> %conv, %s 38 ret <2 x i32> %d 39} 40 41; rdar://11721329 42define i64 @t2(i64 %x, i32 %y) { 43; CHECK-LABEL: @t2( 44; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y:%.*]] to i64 45; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[X:%.*]], [[TMP1]] 46; CHECK-NEXT: ret i64 [[TMP2]] 47; 48 %1 = shl i32 1, %y 49 %2 = zext i32 %1 to i64 50 %3 = udiv i64 %x, %2 51 ret i64 %3 52} 53 54; PR13250 55define i64 @t3(i64 %x, i32 %y) { 56; CHECK-LABEL: @t3( 57; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 2 58; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 59; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[X:%.*]], [[TMP2]] 60; CHECK-NEXT: ret i64 [[TMP3]] 61; 62 %1 = shl i32 4, %y 63 %2 = zext i32 %1 to i64 64 %3 = udiv i64 %x, %2 65 ret i64 %3 66} 67 68define i32 @t4(i32 %x, i32 %y) { 69; CHECK-LABEL: @t4( 70; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 5) 71; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[X:%.*]], [[TMP1]] 72; CHECK-NEXT: ret i32 [[TMP2]] 73; 74 %1 = shl i32 1, %y 75 %2 = icmp ult i32 %1, 32 76 %3 = select i1 %2, i32 32, i32 %1 77 %4 = udiv i32 %x, %3 78 ret i32 %4 79} 80 81define i32 @t5(i1 %x, i1 %y, i32 %V) { 82; CHECK-LABEL: @t5( 83; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i32 5, i32 6 84; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[Y:%.*]], i32 [[TMP1]], i32 [[V:%.*]] 85; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[V]], [[TMP2]] 86; CHECK-NEXT: ret i32 [[TMP3]] 87; 88 %1 = shl i32 1, %V 89 %2 = select i1 %x, i32 32, i32 64 90 %3 = select i1 %y, i32 %2, i32 %1 91 %4 = udiv i32 %V, %3 92 ret i32 %4 93} 94 95define i32 @t6(i32 %x, i32 %z) { 96; CHECK-LABEL: @t6( 97; CHECK-NEXT: [[X_IS_ZERO:%.*]] = icmp eq i32 [[X:%.*]], 0 98; CHECK-NEXT: [[DIVISOR:%.*]] = select i1 [[X_IS_ZERO]], i32 1, i32 [[X]] 99; CHECK-NEXT: [[Y:%.*]] = udiv i32 [[Z:%.*]], [[DIVISOR]] 100; CHECK-NEXT: ret i32 [[Y]] 101; 102 %x_is_zero = icmp eq i32 %x, 0 103 %divisor = select i1 %x_is_zero, i32 1, i32 %x 104 %y = udiv i32 %z, %divisor 105 ret i32 %y 106} 107 108define i8 @udiv_umin(i8 %x, i8 %y, i8 %z) { 109; CHECK-LABEL: @udiv_umin( 110; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[Z:%.*]]) 111; CHECK-NEXT: [[D1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 112; CHECK-NEXT: ret i8 [[D1]] 113; 114 %y2 = shl i8 1, %y 115 %z2 = shl i8 1, %z 116 %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2) 117 %d = udiv i8 %x, %m 118 ret i8 %d 119} 120 121define i8 @udiv_umax(i8 %x, i8 %y, i8 %z) { 122; CHECK-LABEL: @udiv_umax( 123; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[Z:%.*]]) 124; CHECK-NEXT: [[D1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 125; CHECK-NEXT: ret i8 [[D1]] 126; 127 %y2 = shl i8 1, %y 128 %z2 = shl i8 1, %z 129 %m = call i8 @llvm.umax.i8(i8 %y2, i8 %z2) 130 %d = udiv i8 %x, %m 131 ret i8 %d 132} 133 134; Negative test, cannot take exact log2 135define i8 @udiv_umin_(i8 %x, i8 %y, i8 %z) { 136; CHECK-LABEL: @udiv_umin_( 137; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] 138; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z:%.*]]) 139; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] 140; CHECK-NEXT: ret i8 [[D]] 141; 142 %y2 = shl i8 1, %y 143 %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z) 144 %d = udiv i8 %x, %m 145 ret i8 %d 146} 147 148; Negative test, extra use 149define i8 @udiv_umin_extra_use(i8 %x, i8 %y, i8 %z) { 150; CHECK-LABEL: @udiv_umin_extra_use( 151; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] 152; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] 153; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]]) 154; CHECK-NEXT: call void @use(i8 [[M]]) 155; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] 156; CHECK-NEXT: ret i8 [[D]] 157; 158 %y2 = shl i8 1, %y 159 %z2 = shl i8 1, %z 160 %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2) 161 call void @use(i8 %m) 162 %d = udiv i8 %x, %m 163 ret i8 %d 164} 165 166; Negative test, signed min/max 167define i8 @udiv_smin(i8 %x, i8 %y, i8 %z) { 168; CHECK-LABEL: @udiv_smin( 169; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] 170; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] 171; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y2]], i8 [[Z2]]) 172; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] 173; CHECK-NEXT: ret i8 [[D]] 174; 175 %y2 = shl i8 1, %y 176 %z2 = shl i8 1, %z 177 %m = call i8 @llvm.smin.i8(i8 %y2, i8 %z2) 178 %d = udiv i8 %x, %m 179 ret i8 %d 180} 181 182; Negative test, signed min/max 183define i8 @udiv_smax(i8 %x, i8 %y, i8 %z) { 184; CHECK-LABEL: @udiv_smax( 185; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] 186; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] 187; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y2]], i8 [[Z2]]) 188; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] 189; CHECK-NEXT: ret i8 [[D]] 190; 191 %y2 = shl i8 1, %y 192 %z2 = shl i8 1, %z 193 %m = call i8 @llvm.smax.i8(i8 %y2, i8 %z2) 194 %d = udiv i8 %x, %m 195 ret i8 %d 196} 197 198; (X << C1) / X -> 1 << C1 optimizations 199 200define i32 @t7(i32 %x) { 201; CHECK-LABEL: @t7( 202; CHECK-NEXT: ret i32 4 203; 204 %shl = shl nsw i32 %x, 2 205 %r = sdiv i32 %shl, %x 206 ret i32 %r 207} 208 209; make sure the previous opt doesn't take place for wrapped shifts 210 211define i32 @t8(i32 %x) { 212; CHECK-LABEL: @t8( 213; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 2 214; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[SHL]], [[X]] 215; CHECK-NEXT: ret i32 [[R]] 216; 217 %shl = shl i32 %x, 2 218 %r = sdiv i32 %shl, %x 219 ret i32 %r 220} 221 222define <2 x i32> @t9(<2 x i32> %x) { 223; CHECK-LABEL: @t9( 224; CHECK-NEXT: ret <2 x i32> <i32 4, i32 8> 225; 226 %shl = shl nsw <2 x i32> %x, <i32 2, i32 3> 227 %r = sdiv <2 x i32> %shl, %x 228 ret <2 x i32> %r 229} 230 231define i32 @t10(i32 %x, i32 %y) { 232; CHECK-LABEL: @t10( 233; CHECK-NEXT: [[R:%.*]] = shl nsw i32 1, [[Y:%.*]] 234; CHECK-NEXT: ret i32 [[R]] 235; 236 %shl = shl nsw i32 %x, %y 237 %r = sdiv i32 %shl, %x 238 ret i32 %r 239} 240 241define <2 x i32> @t11(<2 x i32> %x, <2 x i32> %y) { 242; CHECK-LABEL: @t11( 243; CHECK-NEXT: [[R:%.*]] = shl nsw <2 x i32> <i32 1, i32 1>, [[Y:%.*]] 244; CHECK-NEXT: ret <2 x i32> [[R]] 245; 246 %shl = shl nsw <2 x i32> %x, %y 247 %r = sdiv <2 x i32> %shl, %x 248 ret <2 x i32> %r 249} 250 251define i32 @t12(i32 %x) { 252; CHECK-LABEL: @t12( 253; CHECK-NEXT: ret i32 4 254; 255 %shl = shl nuw i32 %x, 2 256 %r = udiv i32 %shl, %x 257 ret i32 %r 258} 259 260; make sure the previous opt doesn't take place for wrapped shifts 261 262define i32 @t13(i32 %x) { 263; CHECK-LABEL: @t13( 264; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 2 265; CHECK-NEXT: [[R:%.*]] = udiv i32 [[SHL]], [[X]] 266; CHECK-NEXT: ret i32 [[R]] 267; 268 %shl = shl i32 %x, 2 269 %r = udiv i32 %shl, %x 270 ret i32 %r 271} 272 273define <2 x i32> @t14(<2 x i32> %x) { 274; CHECK-LABEL: @t14( 275; CHECK-NEXT: ret <2 x i32> <i32 4, i32 8> 276; 277 %shl = shl nuw <2 x i32> %x, <i32 2, i32 3> 278 %r = udiv <2 x i32> %shl, %x 279 ret <2 x i32> %r 280} 281 282define i32 @t15(i32 %x, i32 %y) { 283; CHECK-LABEL: @t15( 284; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[Y:%.*]] 285; CHECK-NEXT: ret i32 [[R]] 286; 287 %shl = shl nuw i32 %x, %y 288 %r = udiv i32 %shl, %x 289 ret i32 %r 290} 291 292define <2 x i32> @t16(<2 x i32> %x, <2 x i32> %y) { 293; CHECK-LABEL: @t16( 294; CHECK-NEXT: [[R:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[Y:%.*]] 295; CHECK-NEXT: ret <2 x i32> [[R]] 296; 297 %shl = shl nuw <2 x i32> %x, %y 298 %r = udiv <2 x i32> %shl, %x 299 ret <2 x i32> %r 300} 301