1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i1 @test1(i8 %A) { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: ret i1 true 7; 8 %B = sitofp i8 %A to double 9 %C = fcmp ult double %B, 128.0 10 ret i1 %C 11} 12 13define i1 @test2(i8 %A) { 14; CHECK-LABEL: @test2( 15; CHECK-NEXT: ret i1 true 16; 17 %B = sitofp i8 %A to double 18 %C = fcmp ugt double %B, -128.1 19 ret i1 %C 20} 21 22define i1 @test3(i8 %A) { 23; CHECK-LABEL: @test3( 24; CHECK-NEXT: ret i1 true 25; 26 %B = sitofp i8 %A to double 27 %C = fcmp ule double %B, 127.0 28 ret i1 %C 29} 30 31define i1 @test4(i8 %A) { 32; CHECK-LABEL: @test4( 33; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 127 34; CHECK-NEXT: ret i1 [[C]] 35; 36 %B = sitofp i8 %A to double 37 %C = fcmp ult double %B, 127.0 38 ret i1 %C 39} 40 41define i32 @test5(i32 %A) { 42; CHECK-LABEL: @test5( 43; CHECK-NEXT: ret i32 [[A:%.*]] 44; 45 %B = sitofp i32 %A to double 46 %C = fptosi double %B to i32 47 %D = uitofp i32 %C to double 48 %E = fptoui double %D to i32 49 ret i32 %E 50} 51 52define i32 @test6(i32 %A) { 53; CHECK-LABEL: @test6( 54; CHECK-NEXT: [[ADDCONV:%.*]] = and i32 [[A:%.*]], 39 55; CHECK-NEXT: ret i32 [[ADDCONV]] 56; 57 %B = and i32 %A, 7 58 %C = and i32 %A, 32 59 %D = sitofp i32 %B to double 60 %E = sitofp i32 %C to double 61 %F = fadd double %D, %E 62 %G = fptosi double %F to i32 63 ret i32 %G 64} 65 66define i32 @test7(i32 %A) { 67; CHECK-LABEL: @test7( 68; CHECK-NEXT: ret i32 [[A:%.*]] 69; 70 %B = sitofp i32 %A to double 71 %C = fptoui double %B to i32 72 ret i32 %C 73} 74 75define i32 @test8(i32 %A) { 76; CHECK-LABEL: @test8( 77; CHECK-NEXT: ret i32 [[A:%.*]] 78; 79 %B = uitofp i32 %A to double 80 %C = fptosi double %B to i32 81 ret i32 %C 82} 83 84define i32 @test9(i8 %A) { 85; CHECK-LABEL: @test9( 86; CHECK-NEXT: [[C:%.*]] = zext i8 [[A:%.*]] to i32 87; CHECK-NEXT: ret i32 [[C]] 88; 89 %B = sitofp i8 %A to float 90 %C = fptoui float %B to i32 91 ret i32 %C 92} 93 94define i32 @test10(i8 %A) { 95; CHECK-LABEL: @test10( 96; CHECK-NEXT: [[C:%.*]] = sext i8 [[A:%.*]] to i32 97; CHECK-NEXT: ret i32 [[C]] 98; 99 %B = sitofp i8 %A to float 100 %C = fptosi float %B to i32 101 ret i32 %C 102} 103 104; If the input value is outside of the range of the output cast, it's 105; undefined behavior, so we can assume it fits. 106 107define i8 @test11(i32 %A) { 108; CHECK-LABEL: @test11( 109; CHECK-NEXT: [[C:%.*]] = trunc i32 [[A:%.*]] to i8 110; CHECK-NEXT: ret i8 [[C]] 111; 112 %B = sitofp i32 %A to float 113 %C = fptosi float %B to i8 114 ret i8 %C 115} 116 117; If the input value is negative, it'll be outside the range of the 118; output cast, and thus undefined behavior. 119 120define i32 @test12(i8 %A) { 121; CHECK-LABEL: @test12( 122; CHECK-NEXT: [[C:%.*]] = zext i8 [[A:%.*]] to i32 123; CHECK-NEXT: ret i32 [[C]] 124; 125 %B = sitofp i8 %A to float 126 %C = fptoui float %B to i32 127 ret i32 %C 128} 129 130; This can't fold because the 25-bit input doesn't fit in the mantissa. 131 132define i32 @test13(i25 %A) { 133; CHECK-LABEL: @test13( 134; CHECK-NEXT: [[B:%.*]] = uitofp i25 [[A:%.*]] to float 135; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32 136; CHECK-NEXT: ret i32 [[C]] 137; 138 %B = uitofp i25 %A to float 139 %C = fptoui float %B to i32 140 ret i32 %C 141} 142 143; But this one can. 144 145define i32 @test14(i24 %A) { 146; CHECK-LABEL: @test14( 147; CHECK-NEXT: [[C:%.*]] = zext i24 [[A:%.*]] to i32 148; CHECK-NEXT: ret i32 [[C]] 149; 150 %B = uitofp i24 %A to float 151 %C = fptoui float %B to i32 152 ret i32 %C 153} 154 155; And this one can too. 156 157define i24 @test15(i32 %A) { 158; CHECK-LABEL: @test15( 159; CHECK-NEXT: [[C:%.*]] = trunc i32 [[A:%.*]] to i24 160; CHECK-NEXT: ret i24 [[C]] 161; 162 %B = uitofp i32 %A to float 163 %C = fptoui float %B to i24 164 ret i24 %C 165} 166 167; This can fold because the 25-bit input is signed and we discard the sign bit. 168 169define i32 @test16(i25 %A) { 170; CHECK-LABEL: @test16( 171; CHECK-NEXT: [[C:%.*]] = zext i25 [[A:%.*]] to i32 172; CHECK-NEXT: ret i32 [[C]] 173; 174 %B = sitofp i25 %A to float 175 %C = fptoui float %B to i32 176 ret i32 %C 177} 178 179; This can't fold because the 26-bit input won't fit the mantissa 180; even after discarding the signed bit. 181 182define i32 @test17(i26 %A) { 183; CHECK-LABEL: @test17( 184; CHECK-NEXT: [[B:%.*]] = sitofp i26 [[A:%.*]] to float 185; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32 186; CHECK-NEXT: ret i32 [[C]] 187; 188 %B = sitofp i26 %A to float 189 %C = fptoui float %B to i32 190 ret i32 %C 191} 192 193; This can fold because the 54-bit output is signed and we discard the sign bit. 194 195define i54 @test18(i64 %A) { 196; CHECK-LABEL: @test18( 197; CHECK-NEXT: [[C:%.*]] = trunc i64 [[A:%.*]] to i54 198; CHECK-NEXT: ret i54 [[C]] 199; 200 %B = sitofp i64 %A to double 201 %C = fptosi double %B to i54 202 ret i54 %C 203} 204 205; This can't fold because the 55-bit output won't fit the mantissa 206; even after discarding the sign bit. 207 208define i55 @test19(i64 %A) { 209; CHECK-LABEL: @test19( 210; CHECK-NEXT: [[B:%.*]] = sitofp i64 [[A:%.*]] to double 211; CHECK-NEXT: [[C:%.*]] = fptosi double [[B]] to i55 212; CHECK-NEXT: ret i55 [[C]] 213; 214 %B = sitofp i64 %A to double 215 %C = fptosi double %B to i55 216 ret i55 %C 217} 218 219; TODO: The mask guarantees that the input is small enough to eliminate the FP casts. 220 221define i25 @masked_input(i25 %A) { 222; CHECK-LABEL: @masked_input( 223; CHECK-NEXT: [[M:%.*]] = and i25 [[A:%.*]], 65535 224; CHECK-NEXT: [[B:%.*]] = uitofp i25 [[M]] to float 225; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i25 226; CHECK-NEXT: ret i25 [[C]] 227; 228 %m = and i25 %A, 65535 229 %B = uitofp i25 %m to float 230 %C = fptoui float %B to i25 231 ret i25 %C 232} 233 234; TODO: Clear the low bit - guarantees that the input is converted to FP without rounding. 235 236define i25 @low_masked_input(i25 %A) { 237; CHECK-LABEL: @low_masked_input( 238; CHECK-NEXT: [[M:%.*]] = and i25 [[A:%.*]], -2 239; CHECK-NEXT: [[B:%.*]] = uitofp i25 [[M]] to float 240; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i25 241; CHECK-NEXT: ret i25 [[C]] 242; 243 %m = and i25 %A, -2 244 %B = uitofp i25 %m to float 245 %C = fptoui float %B to i25 246 ret i25 %C 247} 248