1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s 3 4; Tests if an integer type can cover the entire range of an input 5; FP value. If so, we can remove an intermediate cast to a smaller 6; int type (remove a truncate). 7 8define i16 @half_fptoui_i17_i16(half %x) { 9; CHECK-LABEL: @half_fptoui_i17_i16( 10; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i16 11; CHECK-NEXT: ret i16 [[I]] 12; 13 %i = fptoui half %x to i17 14 %r = trunc i17 %i to i16 15 ret i16 %r 16} 17 18; Negative test - not enough bits to hold max half value (65504). 19 20define i15 @half_fptoui_i17_i15(half %x) { 21; CHECK-LABEL: @half_fptoui_i17_i15( 22; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i17 23; CHECK-NEXT: [[R:%.*]] = trunc i17 [[I]] to i15 24; CHECK-NEXT: ret i15 [[R]] 25; 26 %i = fptoui half %x to i17 27 %r = trunc i17 %i to i15 28 ret i15 %r 29} 30 31; Wider intermediate type is ok. 32 33define i16 @half_fptoui_i32_i16(half %x) { 34; CHECK-LABEL: @half_fptoui_i32_i16( 35; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i16 36; CHECK-NEXT: ret i16 [[I]] 37; 38 %i = fptoui half %x to i32 39 %r = trunc i32 %i to i16 40 ret i16 %r 41} 42 43; Wider final type is ok. 44; TODO: Handle non-simple result type. 45 46define i17 @half_fptoui_i32_i17(half %x) { 47; CHECK-LABEL: @half_fptoui_i32_i17( 48; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i32 49; CHECK-NEXT: [[R:%.*]] = trunc i32 [[I]] to i17 50; CHECK-NEXT: ret i17 [[R]] 51; 52 %i = fptoui half %x to i32 53 %r = trunc i32 %i to i17 54 ret i17 %r 55} 56 57; Vectors work too. 58 59define <4 x i16> @half_fptoui_4xi32_4xi16(<4 x half> %x) { 60; CHECK-LABEL: @half_fptoui_4xi32_4xi16( 61; CHECK-NEXT: [[I:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i16> 62; CHECK-NEXT: ret <4 x i16> [[I]] 63; 64 %i = fptoui <4 x half> %x to <4 x i32> 65 %r = trunc <4 x i32> %i to <4 x i16> 66 ret <4 x i16> %r 67} 68 69define i128 @bfloat_fptoui_i129_i128(bfloat %x) { 70; CHECK-LABEL: @bfloat_fptoui_i129_i128( 71; CHECK-NEXT: [[I:%.*]] = fptoui bfloat [[X:%.*]] to i128 72; CHECK-NEXT: ret i128 [[I]] 73; 74 %i = fptoui bfloat %x to i129 75 %r = trunc i129 %i to i128 76 ret i128 %r 77} 78 79; Negative test - not enough bits to hold max bfloat value (2**127 * (2 − 2**−7)) 80 81define i127 @bfloat_fptoui_i128_i127(bfloat %x) { 82; CHECK-LABEL: @bfloat_fptoui_i128_i127( 83; CHECK-NEXT: [[I:%.*]] = fptoui bfloat [[X:%.*]] to i128 84; CHECK-NEXT: [[R:%.*]] = trunc i128 [[I]] to i127 85; CHECK-NEXT: ret i127 [[R]] 86; 87 %i = fptoui bfloat %x to i128 88 %r = trunc i128 %i to i127 89 ret i127 %r 90} 91 92define i128 @float_fptoui_i129_i128(float %x) { 93; CHECK-LABEL: @float_fptoui_i129_i128( 94; CHECK-NEXT: [[I:%.*]] = fptoui float [[X:%.*]] to i128 95; CHECK-NEXT: ret i128 [[I]] 96; 97 %i = fptoui float %x to i129 98 %r = trunc i129 %i to i128 99 ret i128 %r 100} 101 102; TODO: We could transform with multiple users. 103declare void @use(i129) 104define i128 @float_fptoui_i129_i128_use(float %x) { 105; CHECK-LABEL: @float_fptoui_i129_i128_use( 106; CHECK-NEXT: [[I:%.*]] = fptoui float [[X:%.*]] to i129 107; CHECK-NEXT: call void @use(i129 [[I]]) 108; CHECK-NEXT: [[R:%.*]] = trunc i129 [[I]] to i128 109; CHECK-NEXT: ret i128 [[R]] 110; 111 %i = fptoui float %x to i129 112 call void @use(i129 %i) 113 %r = trunc i129 %i to i128 114 ret i128 %r 115} 116 117; Negative test - not enough bits to hold max float value (2**127 * (2 − 2**−23)) 118 119define i127 @float_fptoui_i128_i127(float %x) { 120; CHECK-LABEL: @float_fptoui_i128_i127( 121; CHECK-NEXT: [[I:%.*]] = fptoui float [[X:%.*]] to i128 122; CHECK-NEXT: [[R:%.*]] = trunc i128 [[I]] to i127 123; CHECK-NEXT: ret i127 [[R]] 124; 125 %i = fptoui float %x to i128 126 %r = trunc i128 %i to i127 127 ret i127 %r 128} 129 130define i1024 @double_fptoui_i1025_i1024(double %x) { 131; CHECK-LABEL: @double_fptoui_i1025_i1024( 132; CHECK-NEXT: [[I:%.*]] = fptoui double [[X:%.*]] to i1024 133; CHECK-NEXT: ret i1024 [[I]] 134; 135 %i = fptoui double %x to i1025 136 %r = trunc i1025 %i to i1024 137 ret i1024 %r 138} 139 140; Negative test - not enough bits to hold max double value (2**1023 * (2 − 2**−52)) 141 142define i1023 @double_fptoui_i1024_i1023(double %x) { 143; CHECK-LABEL: @double_fptoui_i1024_i1023( 144; CHECK-NEXT: [[I:%.*]] = fptoui double [[X:%.*]] to i1024 145; CHECK-NEXT: [[R:%.*]] = trunc i1024 [[I]] to i1023 146; CHECK-NEXT: ret i1023 [[R]] 147; 148 %i = fptoui double %x to i1024 149 %r = trunc i1024 %i to i1023 150 ret i1023 %r 151} 152 153; Negative test - not enough bits to hold min half value (-65504). 154 155define i16 @half_fptosi_i17_i16(half %x) { 156; CHECK-LABEL: @half_fptosi_i17_i16( 157; CHECK-NEXT: [[I:%.*]] = fptosi half [[X:%.*]] to i17 158; CHECK-NEXT: [[R:%.*]] = trunc i17 [[I]] to i16 159; CHECK-NEXT: ret i16 [[R]] 160; 161 %i = fptosi half %x to i17 162 %r = trunc i17 %i to i16 163 ret i16 %r 164} 165 166define i17 @half_fptosi_i18_i17(half %x) { 167; CHECK-LABEL: @half_fptosi_i18_i17( 168; CHECK-NEXT: [[I:%.*]] = fptosi half [[X:%.*]] to i17 169; CHECK-NEXT: ret i17 [[I]] 170; 171 %i = fptosi half %x to i18 172 %r = trunc i18 %i to i17 173 ret i17 %r 174} 175 176; Wider intermediate type is ok. 177; TODO: Handle non-simple result type. 178 179define i17 @half_fptosi_i32_i17(half %x) { 180; CHECK-LABEL: @half_fptosi_i32_i17( 181; CHECK-NEXT: [[I:%.*]] = fptosi half [[X:%.*]] to i32 182; CHECK-NEXT: [[R:%.*]] = trunc i32 [[I]] to i17 183; CHECK-NEXT: ret i17 [[R]] 184; 185 %i = fptosi half %x to i32 186 %r = trunc i32 %i to i17 187 ret i17 %r 188} 189 190; Wider final type is ok. 191; TODO: Handle non-simple result type. 192 193define i18 @half_fptosi_i32_i18(half %x) { 194; CHECK-LABEL: @half_fptosi_i32_i18( 195; CHECK-NEXT: [[I:%.*]] = fptosi half [[X:%.*]] to i32 196; CHECK-NEXT: [[R:%.*]] = trunc i32 [[I]] to i18 197; CHECK-NEXT: ret i18 [[R]] 198; 199 %i = fptosi half %x to i32 200 %r = trunc i32 %i to i18 201 ret i18 %r 202} 203 204; Vectors work too. 205 206define <4 x i17> @half_fptosi_4xi32_4xi17(<4 x half> %x) { 207; CHECK-LABEL: @half_fptosi_4xi32_4xi17( 208; CHECK-NEXT: [[I:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i17> 209; CHECK-NEXT: ret <4 x i17> [[I]] 210; 211 %i = fptosi <4 x half> %x to <4 x i32> 212 %r = trunc <4 x i32> %i to <4 x i17> 213 ret <4 x i17> %r 214} 215 216; Negative test - not enough bits to hold min float value. 217 218define i128 @bfloat_fptosi_i129_i128(bfloat %x) { 219; CHECK-LABEL: @bfloat_fptosi_i129_i128( 220; CHECK-NEXT: [[I:%.*]] = fptosi bfloat [[X:%.*]] to i129 221; CHECK-NEXT: [[R:%.*]] = trunc i129 [[I]] to i128 222; CHECK-NEXT: ret i128 [[R]] 223; 224 %i = fptosi bfloat %x to i129 225 %r = trunc i129 %i to i128 226 ret i128 %r 227} 228 229define i129 @bfloat_fptosi_i130_i129(bfloat %x) { 230; CHECK-LABEL: @bfloat_fptosi_i130_i129( 231; CHECK-NEXT: [[I:%.*]] = fptosi bfloat [[X:%.*]] to i129 232; CHECK-NEXT: ret i129 [[I]] 233; 234 %i = fptosi bfloat %x to i130 235 %r = trunc i130 %i to i129 236 ret i129 %r 237} 238 239define i129 @float_fptosi_i130_i129(float %x) { 240; CHECK-LABEL: @float_fptosi_i130_i129( 241; CHECK-NEXT: [[I:%.*]] = fptosi float [[X:%.*]] to i129 242; CHECK-NEXT: ret i129 [[I]] 243; 244 %i = fptosi float %x to i130 245 %r = trunc i130 %i to i129 246 ret i129 %r 247} 248 249; Negative test - not enough bits to hold min float value. 250 251define i128 @float_fptosi_i129_i128(float %x) { 252; CHECK-LABEL: @float_fptosi_i129_i128( 253; CHECK-NEXT: [[I:%.*]] = fptosi float [[X:%.*]] to i129 254; CHECK-NEXT: [[R:%.*]] = trunc i129 [[I]] to i128 255; CHECK-NEXT: ret i128 [[R]] 256; 257 %i = fptosi float %x to i129 258 %r = trunc i129 %i to i128 259 ret i128 %r 260} 261 262define i1025 @double_fptosi_i1026_i1025(double %x) { 263; CHECK-LABEL: @double_fptosi_i1026_i1025( 264; CHECK-NEXT: [[I:%.*]] = fptosi double [[X:%.*]] to i1025 265; CHECK-NEXT: ret i1025 [[I]] 266; 267 %i = fptosi double %x to i1026 268 %r = trunc i1026 %i to i1025 269 ret i1025 %r 270} 271 272; Negative test - not enough bits to hold min double value. 273 274define i1024 @double_fptosi_i1025_i1024(double %x) { 275; CHECK-LABEL: @double_fptosi_i1025_i1024( 276; CHECK-NEXT: [[I:%.*]] = fptosi double [[X:%.*]] to i1025 277; CHECK-NEXT: [[R:%.*]] = trunc i1025 [[I]] to i1024 278; CHECK-NEXT: ret i1024 [[R]] 279; 280 %i = fptosi double %x to i1025 281 %r = trunc i1025 %i to i1024 282 ret i1024 %r 283} 284