1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes='float2int' -S | FileCheck %s -check-prefixes=CHECK,NONE 3; RUN: opt < %s -passes='float2int' -S --data-layout="n64" | FileCheck %s -check-prefixes=CHECK,ONLY64 4; RUN: opt < %s -passes='float2int' -S --data-layout="n8:16:32:64"| FileCheck %s -check-prefixes=CHECK,MULTIPLE 5; RUN: opt < %s -passes=float2int -S --data-layout="e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"| FileCheck %s -check-prefixes=CHECK,PR-79158 6 7; 8; Positive tests 9; 10 11define i16 @simple1(i8 %a) { 12; NONE-LABEL: @simple1( 13; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 14; NONE-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 1 15; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 16; NONE-NEXT: ret i16 [[TMP2]] 17; 18; ONLY64-LABEL: @simple1( 19; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 20; ONLY64-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 1 21; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 22; ONLY64-NEXT: ret i16 [[TMP2]] 23; 24; MULTIPLE-LABEL: @simple1( 25; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 26; MULTIPLE-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 1 27; MULTIPLE-NEXT: ret i16 [[T21]] 28; 29; PR-79158-LABEL: @simple1( 30; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 31; PR-79158-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 1 32; PR-79158-NEXT: ret i16 [[T21]] 33; 34 %t1 = uitofp i8 %a to float 35 %t2 = fadd float %t1, 1.0 36 %t3 = fptoui float %t2 to i16 37 ret i16 %t3 38} 39 40define i8 @simple2(i8 %a) { 41; NONE-LABEL: @simple2( 42; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 43; NONE-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 44; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i8 45; NONE-NEXT: ret i8 [[TMP2]] 46; 47; ONLY64-LABEL: @simple2( 48; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 49; ONLY64-NEXT: [[T21:%.*]] = sub i64 [[TMP1]], 1 50; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i8 51; ONLY64-NEXT: ret i8 [[TMP2]] 52; 53; MULTIPLE-LABEL: @simple2( 54; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 55; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 56; MULTIPLE-NEXT: [[TMP2:%.*]] = trunc i16 [[T21]] to i8 57; MULTIPLE-NEXT: ret i8 [[TMP2]] 58; 59; PR-79158-LABEL: @simple2( 60; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 61; PR-79158-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 62; PR-79158-NEXT: [[TMP2:%.*]] = trunc i16 [[T21]] to i8 63; PR-79158-NEXT: ret i8 [[TMP2]] 64; 65 %t1 = uitofp i8 %a to float 66 %t2 = fsub float %t1, 1.0 67 %t3 = fptoui float %t2 to i8 68 ret i8 %t3 69} 70 71define i32 @simple3(i8 %a) { 72; NONE-LABEL: @simple3( 73; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 74; NONE-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 75; NONE-NEXT: ret i32 [[T21]] 76; 77; ONLY64-LABEL: @simple3( 78; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 79; ONLY64-NEXT: [[T21:%.*]] = sub i64 [[TMP1]], 1 80; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i32 81; ONLY64-NEXT: ret i32 [[TMP2]] 82; 83; MULTIPLE-LABEL: @simple3( 84; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 85; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 86; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i16 [[T21]] to i32 87; MULTIPLE-NEXT: ret i32 [[TMP2]] 88; 89; PR-79158-LABEL: @simple3( 90; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 91; PR-79158-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 92; PR-79158-NEXT: [[TMP2:%.*]] = zext i16 [[T21]] to i32 93; PR-79158-NEXT: ret i32 [[TMP2]] 94; 95 %t1 = uitofp i8 %a to float 96 %t2 = fsub float %t1, 1.0 97 %t3 = fptoui float %t2 to i32 98 ret i32 %t3 99} 100 101define i1 @cmp(i8 %a, i8 %b) { 102; NONE-LABEL: @cmp( 103; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 104; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 105; NONE-NEXT: [[T31:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]] 106; NONE-NEXT: ret i1 [[T31]] 107; 108; ONLY64-LABEL: @cmp( 109; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 110; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 111; ONLY64-NEXT: [[T31:%.*]] = icmp slt i64 [[TMP1]], [[TMP2]] 112; ONLY64-NEXT: ret i1 [[T31]] 113; 114; MULTIPLE-LABEL: @cmp( 115; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 116; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 117; MULTIPLE-NEXT: [[T31:%.*]] = icmp slt i16 [[TMP1]], [[TMP2]] 118; MULTIPLE-NEXT: ret i1 [[T31]] 119; 120; PR-79158-LABEL: @cmp( 121; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 122; PR-79158-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 123; PR-79158-NEXT: [[T31:%.*]] = icmp slt i16 [[TMP1]], [[TMP2]] 124; PR-79158-NEXT: ret i1 [[T31]] 125; 126 %t1 = uitofp i8 %a to float 127 %t2 = uitofp i8 %b to float 128 %t3 = fcmp ult float %t1, %t2 129 ret i1 %t3 130} 131 132define i32 @simple4(i32 %a) { 133; CHECK-LABEL: @simple4( 134; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64 135; CHECK-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 1 136; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i32 137; CHECK-NEXT: ret i32 [[TMP2]] 138; 139 %t1 = uitofp i32 %a to double 140 %t2 = fadd double %t1, 1.0 141 %t3 = fptoui double %t2 to i32 142 ret i32 %t3 143} 144 145define i32 @simple5(i8 %a, i8 %b) { 146; NONE-LABEL: @simple5( 147; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 148; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 149; NONE-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 150; NONE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] 151; NONE-NEXT: ret i32 [[T42]] 152; 153; ONLY64-LABEL: @simple5( 154; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 155; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 156; ONLY64-NEXT: [[T31:%.*]] = add i64 [[TMP1]], 1 157; ONLY64-NEXT: [[T42:%.*]] = mul i64 [[T31]], [[TMP2]] 158; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[T42]] to i32 159; ONLY64-NEXT: ret i32 [[TMP3]] 160; 161; MULTIPLE-LABEL: @simple5( 162; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 163; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 164; MULTIPLE-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 165; MULTIPLE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] 166; MULTIPLE-NEXT: ret i32 [[T42]] 167; 168; PR-79158-LABEL: @simple5( 169; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 170; PR-79158-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 171; PR-79158-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 172; PR-79158-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] 173; PR-79158-NEXT: ret i32 [[T42]] 174; 175 %t1 = uitofp i8 %a to float 176 %t2 = uitofp i8 %b to float 177 %t3 = fadd float %t1, 1.0 178 %t4 = fmul float %t3, %t2 179 %t5 = fptoui float %t4 to i32 180 ret i32 %t5 181} 182 183define i32 @simple6(i8 %a, i8 %b) { 184; NONE-LABEL: @simple6( 185; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 186; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 187; NONE-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] 188; NONE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] 189; NONE-NEXT: ret i32 [[T42]] 190; 191; ONLY64-LABEL: @simple6( 192; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 193; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 194; ONLY64-NEXT: [[T31:%.*]] = sub i64 0, [[TMP1]] 195; ONLY64-NEXT: [[T42:%.*]] = mul i64 [[T31]], [[TMP2]] 196; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[T42]] to i32 197; ONLY64-NEXT: ret i32 [[TMP3]] 198; 199; MULTIPLE-LABEL: @simple6( 200; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 201; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 202; MULTIPLE-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] 203; MULTIPLE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] 204; MULTIPLE-NEXT: ret i32 [[T42]] 205; 206; PR-79158-LABEL: @simple6( 207; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 208; PR-79158-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 209; PR-79158-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] 210; PR-79158-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] 211; PR-79158-NEXT: ret i32 [[T42]] 212; 213 %t1 = uitofp i8 %a to float 214 %t2 = uitofp i8 %b to float 215 %t3 = fneg float %t1 216 %t4 = fmul float %t3, %t2 217 %t5 = fptoui float %t4 to i32 218 ret i32 %t5 219} 220 221; The two chains don't interact - failure of one shouldn't 222; cause failure of the other. 223 224define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) { 225; NONE-LABEL: @multi1( 226; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 227; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 228; NONE-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float 229; NONE-NEXT: [[X1:%.*]] = add i32 [[TMP1]], [[TMP2]] 230; NONE-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] 231; NONE-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 232; NONE-NEXT: [[R:%.*]] = add i32 [[X1]], [[W]] 233; NONE-NEXT: ret i32 [[R]] 234; 235; ONLY64-LABEL: @multi1( 236; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 237; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 238; ONLY64-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float 239; ONLY64-NEXT: [[X1:%.*]] = add i64 [[TMP1]], [[TMP2]] 240; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[X1]] to i32 241; ONLY64-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] 242; ONLY64-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 243; ONLY64-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] 244; ONLY64-NEXT: ret i32 [[R]] 245; 246; MULTIPLE-LABEL: @multi1( 247; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 248; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 249; MULTIPLE-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float 250; MULTIPLE-NEXT: [[X1:%.*]] = add i16 [[TMP1]], [[TMP2]] 251; MULTIPLE-NEXT: [[TMP3:%.*]] = zext i16 [[X1]] to i32 252; MULTIPLE-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] 253; MULTIPLE-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 254; MULTIPLE-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] 255; MULTIPLE-NEXT: ret i32 [[R]] 256; 257; PR-79158-LABEL: @multi1( 258; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 259; PR-79158-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 260; PR-79158-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float 261; PR-79158-NEXT: [[X1:%.*]] = add i16 [[TMP1]], [[TMP2]] 262; PR-79158-NEXT: [[TMP3:%.*]] = zext i16 [[X1]] to i32 263; PR-79158-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] 264; PR-79158-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 265; PR-79158-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] 266; PR-79158-NEXT: ret i32 [[R]] 267; 268 %fa = uitofp i8 %a to float 269 %fb = uitofp i8 %b to float 270 %fc = uitofp i8 %c to float 271 %x = fadd float %fa, %fb 272 %y = fptoui float %x to i32 273 %z = fadd float %fc, %d 274 %w = fptoui float %z to i32 275 %r = add i32 %y, %w 276 ret i32 %r 277} 278 279define i16 @simple_negzero(i8 %a) { 280; NONE-LABEL: @simple_negzero( 281; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 282; NONE-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 0 283; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 284; NONE-NEXT: ret i16 [[TMP2]] 285; 286; ONLY64-LABEL: @simple_negzero( 287; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 288; ONLY64-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 0 289; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 290; ONLY64-NEXT: ret i16 [[TMP2]] 291; 292; MULTIPLE-LABEL: @simple_negzero( 293; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 294; MULTIPLE-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 0 295; MULTIPLE-NEXT: ret i16 [[T21]] 296; 297; PR-79158-LABEL: @simple_negzero( 298; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 299; PR-79158-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 0 300; PR-79158-NEXT: ret i16 [[T21]] 301; 302 %t1 = uitofp i8 %a to float 303 %t2 = fadd fast float %t1, -0.0 304 %t3 = fptoui float %t2 to i16 305 ret i16 %t3 306} 307 308define i32 @simple_negative(i8 %call) { 309; NONE-LABEL: @simple_negative( 310; NONE-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i32 311; NONE-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1]], -3 312; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[MUL1]] to i8 313; NONE-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 314; NONE-NEXT: ret i32 [[CONV3]] 315; 316; ONLY64-LABEL: @simple_negative( 317; ONLY64-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i64 318; ONLY64-NEXT: [[MUL1:%.*]] = mul i64 [[TMP1]], -3 319; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[MUL1]] to i8 320; ONLY64-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 321; ONLY64-NEXT: ret i32 [[CONV3]] 322; 323; MULTIPLE-LABEL: @simple_negative( 324; MULTIPLE-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i16 325; MULTIPLE-NEXT: [[MUL1:%.*]] = mul i16 [[TMP1]], -3 326; MULTIPLE-NEXT: [[TMP2:%.*]] = trunc i16 [[MUL1]] to i8 327; MULTIPLE-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 328; MULTIPLE-NEXT: ret i32 [[CONV3]] 329; 330; PR-79158-LABEL: @simple_negative( 331; PR-79158-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i16 332; PR-79158-NEXT: [[MUL1:%.*]] = mul i16 [[TMP1]], -3 333; PR-79158-NEXT: [[TMP2:%.*]] = trunc i16 [[MUL1]] to i8 334; PR-79158-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 335; PR-79158-NEXT: ret i32 [[CONV3]] 336; 337 %conv1 = sitofp i8 %call to float 338 %mul = fmul float %conv1, -3.000000e+00 339 %conv2 = fptosi float %mul to i8 340 %conv3 = sext i8 %conv2 to i32 341 ret i32 %conv3 342} 343 344define i16 @simple_fneg(i8 %a) { 345; NONE-LABEL: @simple_fneg( 346; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 347; NONE-NEXT: [[T21:%.*]] = sub i32 0, [[TMP1]] 348; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 349; NONE-NEXT: ret i16 [[TMP2]] 350; 351; ONLY64-LABEL: @simple_fneg( 352; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 353; ONLY64-NEXT: [[T21:%.*]] = sub i64 0, [[TMP1]] 354; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 355; ONLY64-NEXT: ret i16 [[TMP2]] 356; 357; MULTIPLE-LABEL: @simple_fneg( 358; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 359; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 0, [[TMP1]] 360; MULTIPLE-NEXT: ret i16 [[T21]] 361; 362; PR-79158-LABEL: @simple_fneg( 363; PR-79158-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 364; PR-79158-NEXT: [[T21:%.*]] = sub i16 0, [[TMP1]] 365; PR-79158-NEXT: ret i16 [[T21]] 366; 367 %t1 = uitofp i8 %a to float 368 %t2 = fneg fast float %t1 369 %t3 = fptoui float %t2 to i16 370 ret i16 %t3 371} 372 373; 374; Negative tests 375; 376 377; The two chains intersect, which means because one fails, no 378; transform can occur. 379 380define i32 @neg_multi1(i8 %a, i8 %b, i8 %c, float %d) { 381; CHECK-LABEL: @neg_multi1( 382; CHECK-NEXT: [[FA:%.*]] = uitofp i8 [[A:%.*]] to float 383; CHECK-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float 384; CHECK-NEXT: [[X:%.*]] = fadd float [[FA]], [[FC]] 385; CHECK-NEXT: [[Y:%.*]] = fptoui float [[X]] to i32 386; CHECK-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] 387; CHECK-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 388; CHECK-NEXT: [[R:%.*]] = add i32 [[Y]], [[W]] 389; CHECK-NEXT: ret i32 [[R]] 390; 391 %fa = uitofp i8 %a to float 392 %fc = uitofp i8 %c to float 393 %x = fadd float %fa, %fc 394 %y = fptoui float %x to i32 395 %z = fadd float %fc, %d 396 %w = fptoui float %z to i32 397 %r = add i32 %y, %w 398 ret i32 %r 399} 400 401; The i32 * i32 = i64, which has 64 bits, which is greater than the 52 bits 402; that can be exactly represented in a double. 403 404define i64 @neg_muld(i32 %a, i32 %b) { 405; CHECK-LABEL: @neg_muld( 406; CHECK-NEXT: [[FA:%.*]] = uitofp i32 [[A:%.*]] to double 407; CHECK-NEXT: [[FB:%.*]] = uitofp i32 [[B:%.*]] to double 408; CHECK-NEXT: [[MUL:%.*]] = fmul double [[FA]], [[FB]] 409; CHECK-NEXT: [[R:%.*]] = fptoui double [[MUL]] to i64 410; CHECK-NEXT: ret i64 [[R]] 411; 412 %fa = uitofp i32 %a to double 413 %fb = uitofp i32 %b to double 414 %mul = fmul double %fa, %fb 415 %r = fptoui double %mul to i64 416 ret i64 %r 417} 418 419; The i16 * i16 = i32, which can't be represented in a float, but can in a 420; double. This should fail, as the written code uses floats, not doubles so 421; the original result may be inaccurate. 422 423define i32 @neg_mulf(i16 %a, i16 %b) { 424; CHECK-LABEL: @neg_mulf( 425; CHECK-NEXT: [[FA:%.*]] = uitofp i16 [[A:%.*]] to float 426; CHECK-NEXT: [[FB:%.*]] = uitofp i16 [[B:%.*]] to float 427; CHECK-NEXT: [[MUL:%.*]] = fmul float [[FA]], [[FB]] 428; CHECK-NEXT: [[R:%.*]] = fptoui float [[MUL]] to i32 429; CHECK-NEXT: ret i32 [[R]] 430; 431 %fa = uitofp i16 %a to float 432 %fb = uitofp i16 %b to float 433 %mul = fmul float %fa, %fb 434 %r = fptoui float %mul to i32 435 ret i32 %r 436} 437 438; "false" doesn't have an icmp equivalent. 439 440define i1 @neg_cmp(i8 %a, i8 %b) { 441; CHECK-LABEL: @neg_cmp( 442; CHECK-NEXT: [[T1:%.*]] = uitofp i8 [[A:%.*]] to float 443; CHECK-NEXT: [[T2:%.*]] = uitofp i8 [[B:%.*]] to float 444; CHECK-NEXT: [[T3:%.*]] = fcmp false float [[T1]], [[T2]] 445; CHECK-NEXT: ret i1 [[T3]] 446; 447 %t1 = uitofp i8 %a to float 448 %t2 = uitofp i8 %b to float 449 %t3 = fcmp false float %t1, %t2 450 ret i1 %t3 451} 452 453; Division isn't a supported operator. 454 455define i16 @neg_div(i8 %a) { 456; CHECK-LABEL: @neg_div( 457; CHECK-NEXT: [[T1:%.*]] = uitofp i8 [[A:%.*]] to float 458; CHECK-NEXT: [[T2:%.*]] = fdiv float [[T1]], 1.000000e+00 459; CHECK-NEXT: [[T3:%.*]] = fptoui float [[T2]] to i16 460; CHECK-NEXT: ret i16 [[T3]] 461; 462 %t1 = uitofp i8 %a to float 463 %t2 = fdiv float %t1, 1.0 464 %t3 = fptoui float %t2 to i16 465 ret i16 %t3 466} 467 468; 1.2 is not an integer. 469 470define i16 @neg_remainder(i8 %a) { 471; CHECK-LABEL: @neg_remainder( 472; CHECK-NEXT: [[T1:%.*]] = uitofp i8 [[A:%.*]] to float 473; CHECK-NEXT: [[T2:%.*]] = fadd float [[T1]], 1.250000e+00 474; CHECK-NEXT: [[T3:%.*]] = fptoui float [[T2]] to i16 475; CHECK-NEXT: ret i16 [[T3]] 476; 477 %t1 = uitofp i8 %a to float 478 %t2 = fadd float %t1, 1.25 479 %t3 = fptoui float %t2 to i16 480 ret i16 %t3 481} 482 483; i80 > i64, which is the largest bitwidth handleable by default. 484 485define i80 @neg_toolarge(i80 %a) { 486; CHECK-LABEL: @neg_toolarge( 487; CHECK-NEXT: [[T1:%.*]] = uitofp i80 [[A:%.*]] to fp128 488; CHECK-NEXT: [[T2:%.*]] = fadd fp128 [[T1]], [[T1]] 489; CHECK-NEXT: [[T3:%.*]] = fptoui fp128 [[T2]] to i80 490; CHECK-NEXT: ret i80 [[T3]] 491; 492 %t1 = uitofp i80 %a to fp128 493 %t2 = fadd fp128 %t1, %t1 494 %t3 = fptoui fp128 %t2 to i80 495 ret i80 %t3 496} 497 498; The sequence %t1..%t3 cannot be converted because %t4 uses %t2. 499 500define i32 @neg_calluser(i32 %value) { 501; CHECK-LABEL: @neg_calluser( 502; CHECK-NEXT: [[T1:%.*]] = sitofp i32 [[VALUE:%.*]] to double 503; CHECK-NEXT: [[T2:%.*]] = fadd double [[T1]], 1.000000e+00 504; CHECK-NEXT: [[T3:%.*]] = fcmp olt double [[T2]], 0.000000e+00 505; CHECK-NEXT: [[T4:%.*]] = tail call double @g(double [[T2]]) 506; CHECK-NEXT: [[T5:%.*]] = fptosi double [[T4]] to i32 507; CHECK-NEXT: [[T6:%.*]] = zext i1 [[T3]] to i32 508; CHECK-NEXT: [[T7:%.*]] = add i32 [[T6]], [[T5]] 509; CHECK-NEXT: ret i32 [[T7]] 510; 511 %t1 = sitofp i32 %value to double 512 %t2 = fadd double %t1, 1.0 513 %t3 = fcmp olt double %t2, 0.000000e+00 514 %t4 = tail call double @g(double %t2) 515 %t5 = fptosi double %t4 to i32 516 %t6 = zext i1 %t3 to i32 517 %t7 = add i32 %t6, %t5 518 ret i32 %t7 519} 520 521declare double @g(double) 522 523define <4 x i16> @neg_vector(<4 x i8> %a) { 524; CHECK-LABEL: @neg_vector( 525; CHECK-NEXT: [[T1:%.*]] = uitofp <4 x i8> [[A:%.*]] to <4 x float> 526; CHECK-NEXT: [[T2:%.*]] = fptoui <4 x float> [[T1]] to <4 x i16> 527; CHECK-NEXT: ret <4 x i16> [[T2]] 528; 529 %t1 = uitofp <4 x i8> %a to <4 x float> 530 %t2 = fptoui <4 x float> %t1 to <4 x i16> 531 ret <4 x i16> %t2 532} 533 534; Don't crash while processing unreachable (non-standard) IR. 535 536define void @PR38502() { 537; CHECK-LABEL: @PR38502( 538; CHECK-NEXT: entry: 539; CHECK-NEXT: ret void 540; CHECK: bogusBB: 541; CHECK-NEXT: [[INC1:%.*]] = fadd double [[INC:%.*]], 1.000000e+00 542; CHECK-NEXT: [[INC]] = fadd double [[INC1]], 1.000000e+00 543; CHECK-NEXT: [[TOBOOL:%.*]] = fcmp une double [[INC]], 0.000000e+00 544; CHECK-NEXT: br label [[BOGUSBB:%.*]] 545; 546entry: 547 ret void 548 549bogusBB: ; preds = %bogusBB 550 %inc1 = fadd double %inc, 1.000000e+00 551 %inc = fadd double %inc1, 1.000000e+00 552 %tobool = fcmp une double %inc, 0.000000e+00 553 br label %bogusBB 554} 555