1; RUN: opt < %s -instcombine -S | FileCheck %s 2 3target datalayout = "n8:32" 4 5; PR4548 6define i8 @udiv_i8(i8 %a, i8 %b) { 7; CHECK-LABEL: @udiv_i8( 8; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b 9; CHECK-NEXT: ret i8 [[DIV]] 10; 11 %za = zext i8 %a to i32 12 %zb = zext i8 %b to i32 13 %udiv = udiv i32 %za, %zb 14 %conv3 = trunc i32 %udiv to i8 15 ret i8 %conv3 16} 17 18define <2 x i8> @udiv_i8_vec(<2 x i8> %a, <2 x i8> %b) { 19; CHECK-LABEL: @udiv_i8_vec( 20; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i8> %a, %b 21; CHECK-NEXT: ret <2 x i8> [[DIV]] 22; 23 %za = zext <2 x i8> %a to <2 x i32> 24 %zb = zext <2 x i8> %b to <2 x i32> 25 %udiv = udiv <2 x i32> %za, %zb 26 %conv3 = trunc <2 x i32> %udiv to <2 x i8> 27 ret <2 x i8> %conv3 28} 29 30define i8 @urem_i8(i8 %a, i8 %b) { 31; CHECK-LABEL: @urem_i8( 32; CHECK-NEXT: [[TMP1:%.*]] = urem i8 %a, %b 33; CHECK-NEXT: ret i8 [[TMP1]] 34; 35 %za = zext i8 %a to i32 36 %zb = zext i8 %b to i32 37 %udiv = urem i32 %za, %zb 38 %conv3 = trunc i32 %udiv to i8 39 ret i8 %conv3 40} 41 42define <2 x i8> @urem_i8_vec(<2 x i8> %a, <2 x i8> %b) { 43; CHECK-LABEL: @urem_i8_vec( 44; CHECK-NEXT: [[TMP1:%.*]] = urem <2 x i8> %a, %b 45; CHECK-NEXT: ret <2 x i8> [[TMP1]] 46; 47 %za = zext <2 x i8> %a to <2 x i32> 48 %zb = zext <2 x i8> %b to <2 x i32> 49 %udiv = urem <2 x i32> %za, %zb 50 %conv3 = trunc <2 x i32> %udiv to <2 x i8> 51 ret <2 x i8> %conv3 52} 53 54define i32 @udiv_i32(i8 %a, i8 %b) { 55; CHECK-LABEL: @udiv_i32( 56; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b 57; CHECK-NEXT: [[UDIV:%.*]] = zext i8 [[DIV]] to i32 58; CHECK-NEXT: ret i32 [[UDIV]] 59; 60 %za = zext i8 %a to i32 61 %zb = zext i8 %b to i32 62 %udiv = udiv i32 %za, %zb 63 ret i32 %udiv 64} 65 66define <2 x i32> @udiv_i32_vec(<2 x i8> %a, <2 x i8> %b) { 67; CHECK-LABEL: @udiv_i32_vec( 68; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i8> %a, %b 69; CHECK-NEXT: [[UDIV:%.*]] = zext <2 x i8> [[DIV]] to <2 x i32> 70; CHECK-NEXT: ret <2 x i32> [[UDIV]] 71; 72 %za = zext <2 x i8> %a to <2 x i32> 73 %zb = zext <2 x i8> %b to <2 x i32> 74 %udiv = udiv <2 x i32> %za, %zb 75 ret <2 x i32> %udiv 76} 77 78define i32 @udiv_i32_multiuse(i8 %a, i8 %b) { 79; CHECK-LABEL: @udiv_i32_multiuse( 80; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32 81; CHECK-NEXT: [[ZB:%.*]] = zext i8 %b to i32 82; CHECK-NEXT: [[UDIV:%.*]] = udiv i32 [[ZA]], [[ZB]] 83; CHECK-NEXT: [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]] 84; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[UDIV]], [[EXTRA_USES]] 85; CHECK-NEXT: ret i32 [[R]] 86; 87 %za = zext i8 %a to i32 88 %zb = zext i8 %b to i32 89 %udiv = udiv i32 %za, %zb 90 %extra_uses = add i32 %za, %zb 91 %r = mul i32 %udiv, %extra_uses 92 ret i32 %r 93} 94 95define i32 @udiv_illegal_type(i9 %a, i9 %b) { 96; CHECK-LABEL: @udiv_illegal_type( 97; CHECK-NEXT: [[DIV:%.*]] = udiv i9 %a, %b 98; CHECK-NEXT: [[UDIV:%.*]] = zext i9 [[DIV]] to i32 99; CHECK-NEXT: ret i32 [[UDIV]] 100; 101 %za = zext i9 %a to i32 102 %zb = zext i9 %b to i32 103 %udiv = udiv i32 %za, %zb 104 ret i32 %udiv 105} 106 107define i32 @urem_i32(i8 %a, i8 %b) { 108; CHECK-LABEL: @urem_i32( 109; CHECK-NEXT: [[TMP1:%.*]] = urem i8 %a, %b 110; CHECK-NEXT: [[UREM:%.*]] = zext i8 [[TMP1]] to i32 111; CHECK-NEXT: ret i32 [[UREM]] 112; 113 %za = zext i8 %a to i32 114 %zb = zext i8 %b to i32 115 %urem = urem i32 %za, %zb 116 ret i32 %urem 117} 118 119define <2 x i32> @urem_i32_vec(<2 x i8> %a, <2 x i8> %b) { 120; CHECK-LABEL: @urem_i32_vec( 121; CHECK-NEXT: [[TMP1:%.*]] = urem <2 x i8> %a, %b 122; CHECK-NEXT: [[UREM:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32> 123; CHECK-NEXT: ret <2 x i32> [[UREM]] 124; 125 %za = zext <2 x i8> %a to <2 x i32> 126 %zb = zext <2 x i8> %b to <2 x i32> 127 %urem = urem <2 x i32> %za, %zb 128 ret <2 x i32> %urem 129} 130 131define i32 @urem_i32_multiuse(i8 %a, i8 %b) { 132; CHECK-LABEL: @urem_i32_multiuse( 133; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32 134; CHECK-NEXT: [[ZB:%.*]] = zext i8 %b to i32 135; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[ZA]], [[ZB]] 136; CHECK-NEXT: [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]] 137; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[UREM]], [[EXTRA_USES]] 138; CHECK-NEXT: ret i32 [[R]] 139; 140 %za = zext i8 %a to i32 141 %zb = zext i8 %b to i32 142 %urem = urem i32 %za, %zb 143 %extra_uses = add i32 %za, %zb 144 %r = mul i32 %urem, %extra_uses 145 ret i32 %r 146} 147 148define i32 @urem_illegal_type(i9 %a, i9 %b) { 149; CHECK-LABEL: @urem_illegal_type( 150; CHECK-NEXT: [[TMP1:%.*]] = urem i9 %a, %b 151; CHECK-NEXT: [[UREM:%.*]] = zext i9 [[TMP1]] to i32 152; CHECK-NEXT: ret i32 [[UREM]] 153; 154 %za = zext i9 %a to i32 155 %zb = zext i9 %b to i32 156 %urem = urem i32 %za, %zb 157 ret i32 %urem 158} 159 160define i32 @udiv_i32_c(i8 %a) { 161; CHECK-LABEL: @udiv_i32_c( 162; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, 10 163; CHECK-NEXT: [[UDIV:%.*]] = zext i8 [[DIV]] to i32 164; CHECK-NEXT: ret i32 [[UDIV]] 165; 166 %za = zext i8 %a to i32 167 %udiv = udiv i32 %za, 10 168 ret i32 %udiv 169} 170 171define <2 x i32> @udiv_i32_c_vec(<2 x i8> %a) { 172; CHECK-LABEL: @udiv_i32_c_vec( 173; CHECK-NEXT: [[TMP1:%.*]] = udiv <2 x i8> %a, <i8 10, i8 17> 174; CHECK-NEXT: [[UDIV:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32> 175; CHECK-NEXT: ret <2 x i32> [[UDIV]] 176; 177 %za = zext <2 x i8> %a to <2 x i32> 178 %udiv = udiv <2 x i32> %za, <i32 10, i32 17> 179 ret <2 x i32> %udiv 180} 181 182define i32 @udiv_i32_c_multiuse(i8 %a) { 183; CHECK-LABEL: @udiv_i32_c_multiuse( 184; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32 185; CHECK-NEXT: [[UDIV:%.*]] = udiv i32 [[ZA]], 10 186; CHECK-NEXT: [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UDIV]], [[ZA]] 187; CHECK-NEXT: ret i32 [[EXTRA_USE]] 188; 189 %za = zext i8 %a to i32 190 %udiv = udiv i32 %za, 10 191 %extra_use = add i32 %za, %udiv 192 ret i32 %extra_use 193} 194 195define i32 @udiv_illegal_type_c(i9 %a) { 196; CHECK-LABEL: @udiv_illegal_type_c( 197; CHECK-NEXT: [[DIV:%.*]] = udiv i9 %a, 10 198; CHECK-NEXT: [[UDIV:%.*]] = zext i9 [[DIV]] to i32 199; CHECK-NEXT: ret i32 [[UDIV]] 200; 201 %za = zext i9 %a to i32 202 %udiv = udiv i32 %za, 10 203 ret i32 %udiv 204} 205 206define i32 @urem_i32_c(i8 %a) { 207; CHECK-LABEL: @urem_i32_c( 208; CHECK-NEXT: [[TMP1:%.*]] = urem i8 %a, 10 209; CHECK-NEXT: [[UREM:%.*]] = zext i8 [[TMP1]] to i32 210; CHECK-NEXT: ret i32 [[UREM]] 211; 212 %za = zext i8 %a to i32 213 %urem = urem i32 %za, 10 214 ret i32 %urem 215} 216 217define <2 x i32> @urem_i32_c_vec(<2 x i8> %a) { 218; CHECK-LABEL: @urem_i32_c_vec( 219; CHECK-NEXT: [[TMP1:%.*]] = urem <2 x i8> %a, <i8 10, i8 17> 220; CHECK-NEXT: [[UREM:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32> 221; CHECK-NEXT: ret <2 x i32> [[UREM]] 222; 223 %za = zext <2 x i8> %a to <2 x i32> 224 %urem = urem <2 x i32> %za, <i32 10, i32 17> 225 ret <2 x i32> %urem 226} 227 228define i32 @urem_i32_c_multiuse(i8 %a) { 229; CHECK-LABEL: @urem_i32_c_multiuse( 230; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32 231; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[ZA]], 10 232; CHECK-NEXT: [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UREM]], [[ZA]] 233; CHECK-NEXT: ret i32 [[EXTRA_USE]] 234; 235 %za = zext i8 %a to i32 236 %urem = urem i32 %za, 10 237 %extra_use = add i32 %za, %urem 238 ret i32 %extra_use 239} 240 241define i32 @urem_illegal_type_c(i9 %a) { 242; CHECK-LABEL: @urem_illegal_type_c( 243; CHECK-NEXT: [[TMP1:%.*]] = urem i9 %a, 10 244; CHECK-NEXT: [[UREM:%.*]] = zext i9 [[TMP1]] to i32 245; CHECK-NEXT: ret i32 [[UREM]] 246; 247 %za = zext i9 %a to i32 248 %urem = urem i32 %za, 10 249 ret i32 %urem 250} 251 252define i32 @udiv_c_i32(i8 %a) { 253; CHECK-LABEL: @udiv_c_i32( 254; CHECK-NEXT: [[TMP1:%.*]] = udiv i8 10, %a 255; CHECK-NEXT: [[UDIV:%.*]] = zext i8 [[TMP1]] to i32 256; CHECK-NEXT: ret i32 [[UDIV]] 257; 258 %za = zext i8 %a to i32 259 %udiv = udiv i32 10, %za 260 ret i32 %udiv 261} 262 263define i32 @urem_c_i32(i8 %a) { 264; CHECK-LABEL: @urem_c_i32( 265; CHECK-NEXT: [[TMP1:%.*]] = urem i8 10, %a 266; CHECK-NEXT: [[UREM:%.*]] = zext i8 [[TMP1]] to i32 267; CHECK-NEXT: ret i32 [[UREM]] 268; 269 %za = zext i8 %a to i32 270 %urem = urem i32 10, %za 271 ret i32 %urem 272} 273 274; Make sure constexpr is handled. 275 276@b = external global [1 x i8] 277 278define i32 @udiv_constexpr(i8 %a) { 279; CHECK-LABEL: @udiv_constexpr( 280; CHECK-NEXT: [[TMP1:%.*]] = udiv i8 %a, ptrtoint ([1 x i8]* @b to i8) 281; CHECK-NEXT: [[D:%.*]] = zext i8 [[TMP1]] to i32 282; CHECK-NEXT: ret i32 [[D]] 283; 284 %za = zext i8 %a to i32 285 %d = udiv i32 %za, zext (i8 ptrtoint ([1 x i8]* @b to i8) to i32) 286 ret i32 %d 287} 288 289