1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i8 @add-shl-sdiv-scalar0(i8 %x) { 5; CHECK-LABEL: @add-shl-sdiv-scalar0( 6; CHECK-NEXT: [[RZ:%.*]] = srem i8 [[X:%.*]], 4 7; CHECK-NEXT: ret i8 [[RZ]] 8; 9 %sd = sdiv i8 %x, -4 10 %sl = shl i8 %sd, 2 11 %rz = add i8 %sl, %x 12 ret i8 %rz 13} 14 15define i8 @add-shl-sdiv-scalar1(i8 %x) { 16; CHECK-LABEL: @add-shl-sdiv-scalar1( 17; CHECK-NEXT: [[RZ:%.*]] = srem i8 [[X:%.*]], 64 18; CHECK-NEXT: ret i8 [[RZ]] 19; 20 %sd = sdiv i8 %x, -64 21 %sl = shl i8 %sd, 6 22 %rz = add i8 %sl, %x 23 ret i8 %rz 24} 25 26define i32 @add-shl-sdiv-scalar2(i32 %x) { 27; CHECK-LABEL: @add-shl-sdiv-scalar2( 28; CHECK-NEXT: [[RZ:%.*]] = srem i32 [[X:%.*]], 1073741824 29; CHECK-NEXT: ret i32 [[RZ]] 30; 31 %sd = sdiv i32 %x, -1073741824 32 %sl = shl i32 %sd, 30 33 %rz = add i32 %sl, %x 34 ret i32 %rz 35} 36 37; Splat vectors 38 39define <3 x i8> @add-shl-sdiv-splat0(<3 x i8> %x) { 40; CHECK-LABEL: @add-shl-sdiv-splat0( 41; CHECK-NEXT: [[RZ:%.*]] = srem <3 x i8> [[X:%.*]], <i8 4, i8 4, i8 4> 42; CHECK-NEXT: ret <3 x i8> [[RZ]] 43; 44 %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4> 45 %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2> 46 %rz = add <3 x i8> %sl, %x 47 ret <3 x i8> %rz 48} 49 50define <4 x i32> @add-shl-sdiv-splat1(<4 x i32> %x) { 51; CHECK-LABEL: @add-shl-sdiv-splat1( 52; CHECK-NEXT: [[RZ:%.*]] = srem <4 x i32> [[X:%.*]], <i32 1073741824, i32 1073741824, i32 1073741824, i32 1073741824> 53; CHECK-NEXT: ret <4 x i32> [[RZ]] 54; 55 %sd = sdiv <4 x i32> %x, <i32 -1073741824, i32 -1073741824, i32 -1073741824, i32 -1073741824> 56 %sl = shl <4 x i32> %sd, <i32 30, i32 30, i32 30, i32 30> 57 %rz = add <4 x i32> %sl, %x 58 ret <4 x i32> %rz 59} 60 61define <2 x i64> @add-shl-sdiv-splat2(<2 x i64> %x) { 62; CHECK-LABEL: @add-shl-sdiv-splat2( 63; CHECK-NEXT: [[RZ:%.*]] = srem <2 x i64> [[X:%.*]], <i64 32, i64 32> 64; CHECK-NEXT: ret <2 x i64> [[RZ]] 65; 66 %sd = sdiv <2 x i64> %x, <i64 -32, i64 -32> 67 %sl = shl <2 x i64> %sd, <i64 5, i64 5> 68 %rz = add <2 x i64> %sl, %x 69 ret <2 x i64> %rz 70} 71 72; One-use tests 73 74declare void @use32(i32) 75define i32 @add-shl-sdiv-i32-4-use0(i32 %x) { 76; CHECK-LABEL: @add-shl-sdiv-i32-4-use0( 77; CHECK-NEXT: call void @use32(i32 [[X:%.*]]) 78; CHECK-NEXT: [[RZ:%.*]] = srem i32 [[X]], 16 79; CHECK-NEXT: ret i32 [[RZ]] 80; 81 call void @use32(i32 %x) 82 %sd = sdiv i32 %x, -16 83 %sl = shl i32 %sd, 4 84 %rz = add i32 %sl, %x 85 ret i32 %rz 86} 87 88define i32 @add-shl-sdiv-i32-use1(i32 %x) { 89; CHECK-LABEL: @add-shl-sdiv-i32-use1( 90; CHECK-NEXT: [[SD:%.*]] = sdiv i32 [[X:%.*]], -16 91; CHECK-NEXT: call void @use32(i32 [[SD]]) 92; CHECK-NEXT: [[RZ:%.*]] = srem i32 [[X]], 16 93; CHECK-NEXT: ret i32 [[RZ]] 94; 95 %sd = sdiv i32 %x, -16 96 call void @use32(i32 %sd) 97 %sl = shl i32 %sd, 4 98 %rz = add i32 %sl, %x 99 ret i32 %rz 100} 101 102define i32 @add-shl-sdiv-i32-use2(i32 %x) { 103; CHECK-LABEL: @add-shl-sdiv-i32-use2( 104; CHECK-NEXT: [[SD:%.*]] = sdiv i32 [[X:%.*]], -16 105; CHECK-NEXT: [[SL:%.*]] = shl i32 [[SD]], 4 106; CHECK-NEXT: call void @use32(i32 [[SL]]) 107; CHECK-NEXT: [[RZ:%.*]] = srem i32 [[X]], 16 108; CHECK-NEXT: ret i32 [[RZ]] 109; 110 %sd = sdiv i32 %x, -16 111 %sl = shl i32 %sd, 4 112 call void @use32(i32 %sl) 113 %rz = add i32 %sl, %x 114 ret i32 %rz 115} 116 117define i32 @add-shl-sdiv-i32-use3(i32 %x) { 118; CHECK-LABEL: @add-shl-sdiv-i32-use3( 119; CHECK-NEXT: [[SD:%.*]] = sdiv i32 [[X:%.*]], -16 120; CHECK-NEXT: call void @use32(i32 [[SD]]) 121; CHECK-NEXT: [[SL:%.*]] = shl i32 [[SD]], 4 122; CHECK-NEXT: call void @use32(i32 [[SL]]) 123; CHECK-NEXT: [[RZ:%.*]] = srem i32 [[X]], 16 124; CHECK-NEXT: ret i32 [[RZ]] 125; 126 %sd = sdiv i32 %x, -16 127 call void @use32(i32 %sd) 128 %sl = shl i32 %sd, 4 129 call void @use32(i32 %sl) 130 %rz = add i32 %sl, %x 131 ret i32 %rz 132} 133 134declare void @use3xi8(<3 x i8>) 135define <3 x i8> @add-shl-sdiv-use4(<3 x i8> %x) { 136; CHECK-LABEL: @add-shl-sdiv-use4( 137; CHECK-NEXT: [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], <i8 -4, i8 -4, i8 -4> 138; CHECK-NEXT: call void @use3xi8(<3 x i8> [[SD]]) 139; CHECK-NEXT: [[RZ:%.*]] = srem <3 x i8> [[X]], <i8 4, i8 4, i8 4> 140; CHECK-NEXT: ret <3 x i8> [[RZ]] 141; 142 %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4> 143 call void @use3xi8(<3 x i8> %sd) 144 %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2> 145 %rz = add <3 x i8> %sl, %x 146 ret <3 x i8> %rz 147} 148 149; Negative 150 151define i8 @add-shl-sdiv-negative0(i8 %x) { 152; CHECK-LABEL: @add-shl-sdiv-negative0( 153; CHECK-NEXT: [[SD:%.*]] = sdiv i8 [[X:%.*]], 4 154; CHECK-NEXT: [[SL:%.*]] = shl nsw i8 [[SD]], 2 155; CHECK-NEXT: [[RZ:%.*]] = add i8 [[SL]], [[X]] 156; CHECK-NEXT: ret i8 [[RZ]] 157; 158 %sd = sdiv i8 %x, 4 159 %sl = shl i8 %sd, 2 160 %rz = add i8 %sl, %x 161 ret i8 %rz 162} 163 164define i32 @add-shl-sdiv-negative1(i32 %x) { 165; CHECK-LABEL: @add-shl-sdiv-negative1( 166; CHECK-NEXT: [[RZ:%.*]] = sub i32 0, [[X:%.*]] 167; CHECK-NEXT: ret i32 [[RZ]] 168; 169 %sd = sdiv i32 %x, -1 170 %sl = shl i32 %sd, 1 171 %rz = add i32 %sl, %x 172 ret i32 %rz 173} 174 175define i32 @add-shl-sdiv-negative2(i32 %x) { 176; CHECK-LABEL: @add-shl-sdiv-negative2( 177; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], -2147483648 178; CHECK-NEXT: [[SL:%.*]] = select i1 [[TMP1]], i32 -2147483648, i32 0 179; CHECK-NEXT: [[RZ:%.*]] = add i32 [[SL]], [[X]] 180; CHECK-NEXT: ret i32 [[RZ]] 181; 182 %sd = sdiv i32 %x, -2147483648 183 %sl = shl i32 %sd, 31 184 %rz = add i32 %sl, %x 185 ret i32 %rz 186} 187 188define <3 x i8> @add-shl-sdiv-negative3(<3 x i8> %x) { 189; CHECK-LABEL: @add-shl-sdiv-negative3( 190; CHECK-NEXT: [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], <i8 -5, i8 -5, i8 -5> 191; CHECK-NEXT: [[SL:%.*]] = shl <3 x i8> [[SD]], <i8 2, i8 2, i8 2> 192; CHECK-NEXT: [[RZ:%.*]] = add <3 x i8> [[SL]], [[X]] 193; CHECK-NEXT: ret <3 x i8> [[RZ]] 194; 195 %sd = sdiv <3 x i8> %x, <i8 -5, i8 -5, i8 -5> 196 %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2> 197 %rz = add <3 x i8> %sl, %x 198 ret <3 x i8> %rz 199} 200 201define <2 x i64> @add-shl-sdiv-negative4(<2 x i64> %x) { 202; CHECK-LABEL: @add-shl-sdiv-negative4( 203; CHECK-NEXT: ret <2 x i64> undef 204; 205 %sd = sdiv <2 x i64> %x, <i64 32, i64 32> 206 %sl = shl <2 x i64> %sd, <i64 -5, i64 -5> 207 %rz = add <2 x i64> %sl, %x 208 ret <2 x i64> %rz 209} 210 211; Vectors with undef values 212 213define <3 x i8> @add-shl-sdiv-3xi8-undef0(<3 x i8> %x) { 214; CHECK-LABEL: @add-shl-sdiv-3xi8-undef0( 215; CHECK-NEXT: ret <3 x i8> [[X:%.*]] 216; 217 %sd = sdiv <3 x i8> %x, <i8 -4, i8 undef, i8 -4> 218 %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2> 219 %rz = add <3 x i8> %sl, %x 220 ret <3 x i8> %rz 221} 222 223define <3 x i8> @add-shl-sdiv-3xi8-undef1(<3 x i8> %x) { 224; CHECK-LABEL: @add-shl-sdiv-3xi8-undef1( 225; CHECK-NEXT: [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], <i8 -4, i8 -4, i8 -4> 226; CHECK-NEXT: [[SL:%.*]] = shl <3 x i8> [[SD]], <i8 2, i8 undef, i8 2> 227; CHECK-NEXT: [[RZ:%.*]] = add <3 x i8> [[SL]], [[X]] 228; CHECK-NEXT: ret <3 x i8> [[RZ]] 229; 230 %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4> 231 %sl = shl <3 x i8> %sd, <i8 2, i8 undef, i8 2> 232 %rz = add <3 x i8> %sl, %x 233 ret <3 x i8> %rz 234} 235 236; Non-splat vectors 237 238define <2 x i64> @add-shl-sdiv-nonsplat0(<2 x i64> %x) { 239; CHECK-LABEL: @add-shl-sdiv-nonsplat0( 240; CHECK-NEXT: [[SD:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 -32, i64 -64> 241; CHECK-NEXT: [[SL:%.*]] = shl <2 x i64> [[SD]], <i64 5, i64 6> 242; CHECK-NEXT: [[RZ:%.*]] = add <2 x i64> [[SL]], [[X]] 243; CHECK-NEXT: ret <2 x i64> [[RZ]] 244; 245 %sd = sdiv <2 x i64> %x, <i64 -32, i64 -64> 246 %sl = shl <2 x i64> %sd, <i64 5, i64 6> 247 %rz = add <2 x i64> %sl, %x 248 ret <2 x i64> %rz 249} 250 251define <3 x i8> @add-shl-sdiv-nonsplat1(<3 x i8> %x) { 252; CHECK-LABEL: @add-shl-sdiv-nonsplat1( 253; CHECK-NEXT: [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], <i8 -4, i8 -4, i8 -4> 254; CHECK-NEXT: [[SL:%.*]] = shl <3 x i8> [[SD]], <i8 2, i8 2, i8 3> 255; CHECK-NEXT: [[RZ:%.*]] = add <3 x i8> [[SL]], [[X]] 256; CHECK-NEXT: ret <3 x i8> [[RZ]] 257; 258 %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4> 259 %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 3> 260 %rz = add <3 x i8> %sl, %x 261 ret <3 x i8> %rz 262} 263