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