1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instsimplify < %s | FileCheck %s 3 4define float @ldexp_f32_undef_undef() { 5; CHECK-LABEL: @ldexp_f32_undef_undef( 6; CHECK-NEXT: ret float 0x7FF8000000000000 7; 8 %call = call float @llvm.ldexp.f32.i32(float undef, i32 undef) 9 ret float %call 10} 11 12define float @ldexp_f32_poison_undef() { 13; CHECK-LABEL: @ldexp_f32_poison_undef( 14; CHECK-NEXT: ret float poison 15; 16 %call = call float @llvm.ldexp.f32.i32(float poison, i32 undef) 17 ret float %call 18} 19 20define float @ldexp_f32_undef_poison() { 21; CHECK-LABEL: @ldexp_f32_undef_poison( 22; CHECK-NEXT: ret float undef 23; 24 %call = call float @llvm.ldexp.f32.i32(float undef, i32 poison) 25 ret float %call 26} 27 28define float @ldexp_f32_poison_poison() { 29; CHECK-LABEL: @ldexp_f32_poison_poison( 30; CHECK-NEXT: ret float poison 31; 32 %call = call float @llvm.ldexp.f32.i32(float poison, i32 poison) 33 ret float %call 34} 35 36; If the exponent is 0, it doesn't matter if the first argument is 37; constant or not. 38define void @ldexp_f32_exp0(float %x) { 39; CHECK-LABEL: @ldexp_f32_exp0( 40; CHECK-NEXT: store volatile float [[X:%.*]], ptr addrspace(1) undef, align 4 41; CHECK-NEXT: store volatile float [[X]], ptr addrspace(1) undef, align 4 42; CHECK-NEXT: [[ONE:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 1) 43; CHECK-NEXT: store volatile float [[ONE]], ptr addrspace(1) undef, align 4 44; CHECK-NEXT: ret void 45; 46 %zero = call float @llvm.ldexp.f32.i32(float %x, i32 0) 47 store volatile float %zero, ptr addrspace(1) undef 48 49 %undef = call float @llvm.ldexp.f32.i32(float %x, i32 undef) 50 store volatile float %undef, ptr addrspace(1) undef 51 52 %one = call float @llvm.ldexp.f32.i32(float %x, i32 1) 53 store volatile float %one, ptr addrspace(1) undef 54 ret void 55} 56 57define void @ldexp_v2f32_exp0(<2 x float> %x) { 58; CHECK-LABEL: @ldexp_v2f32_exp0( 59; CHECK-NEXT: store volatile <2 x float> [[X:%.*]], ptr addrspace(1) undef, align 8 60; CHECK-NEXT: [[PART_UNDEF1:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> <i32 undef, i32 0>) 61; CHECK-NEXT: store volatile <2 x float> [[PART_UNDEF1]], ptr addrspace(1) undef, align 8 62; CHECK-NEXT: store volatile <2 x float> [[X]], ptr addrspace(1) undef, align 8 63; CHECK-NEXT: ret void 64; 65 %part.undef0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 0, i32 poison>) 66 store volatile <2 x float> %part.undef0, ptr addrspace(1) undef 67 68 %part.undef1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 undef, i32 0>) 69 store volatile <2 x float> %part.undef1, ptr addrspace(1) undef 70 71 %zero = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> zeroinitializer) 72 store volatile <2 x float> %zero, ptr addrspace(1) undef 73 ret void 74} 75 76; Test variable exponent but zero or undef value. 77define void @ldexp_f32_val0(i32 %y) { 78; CHECK-LABEL: @ldexp_f32_val0( 79; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 80; CHECK-NEXT: store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4 81; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 82; CHECK-NEXT: ret void 83; 84 %zero = call float @llvm.ldexp.f32.i32(float 0.0, i32 %y) 85 store volatile float %zero, ptr addrspace(1) undef 86 87 %neg.zero = call float @llvm.ldexp.f32.i32(float -0.0, i32 %y) 88 store volatile float %neg.zero, ptr addrspace(1) undef 89 90 %undef = call float @llvm.ldexp.f32.i32(float undef, i32 %y) 91 store volatile float %undef, ptr addrspace(1) undef 92 ret void 93} 94 95define void @ldexp_f32_val_infinity(i32 %y) { 96; CHECK-LABEL: @ldexp_f32_val_infinity( 97; CHECK-NEXT: store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4 98; CHECK-NEXT: store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4 99; CHECK-NEXT: store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4 100; CHECK-NEXT: store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4 101; CHECK-NEXT: ret void 102; 103 %inf = call float @llvm.ldexp.f32.i32(float 0x7ff0000000000000, i32 %y) 104 store volatile float %inf, ptr addrspace(1) undef 105 106 %neg.inf = call float @llvm.ldexp.f32.i32(float 0xfff0000000000000, i32 %y) 107 store volatile float %neg.inf, ptr addrspace(1) undef 108 109 %inf.zero = call float @llvm.ldexp.f32.i32(float 0x7ff0000000000000, i32 0) 110 store volatile float %inf.zero, ptr addrspace(1) undef 111 112 %neg.inf.zero = call float @llvm.ldexp.f32.i32(float 0xfff0000000000000, i32 0) 113 store volatile float %neg.inf.zero, ptr addrspace(1) undef 114 115 ret void 116} 117 118; Signaling nan should be quieted. 119; Technically this depends on the ieee_mode in the mode register. 120define void @ldexp_f32_val_nan(i32 %y) { 121; CHECK-LABEL: @ldexp_f32_val_nan( 122; CHECK-NEXT: store volatile float 0x7FF8001000000000, ptr addrspace(1) undef, align 4 123; CHECK-NEXT: store volatile float 0xFFF8000100000000, ptr addrspace(1) undef, align 4 124; CHECK-NEXT: store volatile float 0x7FF8000020000000, ptr addrspace(1) undef, align 4 125; CHECK-NEXT: store volatile float 0xFFFFFFFFE0000000, ptr addrspace(1) undef, align 4 126; CHECK-NEXT: ret void 127; 128 %plus.qnan = call float @llvm.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y) 129 store volatile float %plus.qnan, ptr addrspace(1) undef 130 131 %neg.qnan = call float @llvm.ldexp.f32.i32(float 0xfff0000100000000, i32 %y) 132 store volatile float %neg.qnan, ptr addrspace(1) undef 133 134 %plus.snan = call float @llvm.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y) 135 store volatile float %plus.snan, ptr addrspace(1) undef 136 137 %neg.snan = call float @llvm.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y) 138 store volatile float %neg.snan, ptr addrspace(1) undef 139 140 ret void 141} 142 143define void @ldexp_f32_val_nan_strictfp_maytrap(i32 %y) #0 { 144; CHECK-LABEL: @ldexp_f32_val_nan_strictfp_maytrap( 145; CHECK-NEXT: [[PLUS_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0001000000000, i32 [[Y:%.*]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0:[0-9]+]] 146; CHECK-NEXT: store volatile float [[PLUS_QNAN]], ptr addrspace(1) undef, align 4 147; CHECK-NEXT: [[NEG_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF0000100000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 148; CHECK-NEXT: store volatile float [[NEG_QNAN]], ptr addrspace(1) undef, align 4 149; CHECK-NEXT: [[PLUS_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 150; CHECK-NEXT: store volatile float [[PLUS_SNAN]], ptr addrspace(1) undef, align 4 151; CHECK-NEXT: [[NEG_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 152; CHECK-NEXT: store volatile float [[NEG_SNAN]], ptr addrspace(1) undef, align 4 153; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 154; CHECK-NEXT: ret void 155; 156 %plus.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 157 store volatile float %plus.qnan, ptr addrspace(1) undef 158 159 %neg.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xfff0000100000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 160 store volatile float %neg.qnan, ptr addrspace(1) undef 161 162 %plus.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 163 store volatile float %plus.snan, ptr addrspace(1) undef 164 165 %neg.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 166 store volatile float %neg.snan, ptr addrspace(1) undef 167 168 %undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 169 store volatile float %undef, ptr addrspace(1) undef 170 171 ret void 172} 173 174 175define void @ldexp_f32_val_nan_strictfp_strict(i32 %y) #0 { 176; CHECK-LABEL: @ldexp_f32_val_nan_strictfp_strict( 177; CHECK-NEXT: [[PLUS_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0001000000000, i32 [[Y:%.*]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] 178; CHECK-NEXT: store volatile float [[PLUS_QNAN]], ptr addrspace(1) undef, align 4 179; CHECK-NEXT: [[NEG_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF0000100000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] 180; CHECK-NEXT: store volatile float [[NEG_QNAN]], ptr addrspace(1) undef, align 4 181; CHECK-NEXT: [[PLUS_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] 182; CHECK-NEXT: store volatile float [[PLUS_SNAN]], ptr addrspace(1) undef, align 4 183; CHECK-NEXT: [[NEG_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] 184; CHECK-NEXT: store volatile float [[NEG_SNAN]], ptr addrspace(1) undef, align 4 185; CHECK-NEXT: [[UNDEF:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] 186; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 187; CHECK-NEXT: ret void 188; 189 %plus.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 190 store volatile float %plus.qnan, ptr addrspace(1) undef 191 192 %neg.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xfff0000100000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 193 store volatile float %neg.qnan, ptr addrspace(1) undef 194 195 %plus.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 196 store volatile float %plus.snan, ptr addrspace(1) undef 197 198 %neg.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 199 store volatile float %neg.snan, ptr addrspace(1) undef 200 201 %undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 202 store volatile float %undef, ptr addrspace(1) undef 203 204 ret void 205} 206 207define void @ldexp_f32_0() { 208; CHECK-LABEL: @ldexp_f32_0( 209; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 210; CHECK-NEXT: store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4 211; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 212; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 213; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 214; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 215; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 216; CHECK-NEXT: ret void 217; 218 %zero = call float @llvm.ldexp.f32.i32(float 0.0, i32 0) 219 store volatile float %zero, ptr addrspace(1) undef 220 221 %neg.zero = call float @llvm.ldexp.f32.i32(float -0.0, i32 0) 222 store volatile float %neg.zero, ptr addrspace(1) undef 223 224 %one = call float @llvm.ldexp.f32.i32(float 0.0, i32 1) 225 store volatile float %one, ptr addrspace(1) undef 226 227 %min.exp = call float @llvm.ldexp.f32.i32(float 0.0, i32 -126) 228 store volatile float %min.exp, ptr addrspace(1) undef 229 230 %min.exp.sub1 = call float @llvm.ldexp.f32.i32(float 0.0, i32 -127) 231 store volatile float %min.exp.sub1, ptr addrspace(1) undef 232 233 %max.exp = call float @llvm.ldexp.f32.i32(float 0.0, i32 127) 234 store volatile float %max.exp, ptr addrspace(1) undef 235 236 %max.exp.plus1 = call float @llvm.ldexp.f32.i32(float 0.0, i32 128) 237 store volatile float %max.exp.plus1, ptr addrspace(1) undef 238 239 ret void 240} 241 242define void @ldexp_f32_undef_strictfp(float %x, i32 %y) #0 { 243; CHECK-LABEL: @ldexp_f32_undef_strictfp( 244; CHECK-NEXT: [[UNDEF_EXP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X:%.*]], i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 245; CHECK-NEXT: store volatile float [[UNDEF_EXP]], ptr addrspace(1) undef, align 4 246; CHECK-NEXT: store volatile float [[X]], ptr addrspace(1) undef, align 4 247; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 248; CHECK-NEXT: store volatile float poison, ptr addrspace(1) undef, align 4 249; CHECK-NEXT: store volatile float poison, ptr addrspace(1) undef, align 4 250; CHECK-NEXT: store volatile float undef, ptr addrspace(1) undef, align 4 251; CHECK-NEXT: ret void 252; 253 %undef.exp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 254 store volatile float %undef.exp, ptr addrspace(1) undef 255 %poison.exp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 poison, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 256 store volatile float %poison.exp, ptr addrspace(1) undef 257 %undef.val = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 258 store volatile float %undef.val, ptr addrspace(1) undef 259 %poison.val = call float @llvm.experimental.constrained.ldexp.f32.i32(float poison, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 260 store volatile float %poison.val, ptr addrspace(1) undef 261 %poison.undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float poison, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 262 store volatile float %poison.undef, ptr addrspace(1) undef 263 %undef.poison = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 poison, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 264 store volatile float %undef.poison, ptr addrspace(1) undef 265 ret void 266} 267 268; Should be able to ignore strictfp in this case 269define void @ldexp_f32_0_strictfp(float %x) #0 { 270; CHECK-LABEL: @ldexp_f32_0_strictfp( 271; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 272; CHECK-NEXT: store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4 273; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 274; CHECK-NEXT: [[UNKNOWN_ZERO:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X:%.*]], i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 275; CHECK-NEXT: store volatile float [[UNKNOWN_ZERO]], ptr addrspace(1) undef, align 4 276; CHECK-NEXT: [[UNKNOWN_UNDEF:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X]], i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 277; CHECK-NEXT: store volatile float [[UNKNOWN_UNDEF]], ptr addrspace(1) undef, align 4 278; CHECK-NEXT: [[DENORMAL_0:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 279; CHECK-NEXT: store volatile float [[DENORMAL_0]], ptr addrspace(1) undef, align 4 280; CHECK-NEXT: [[DENORMAL_1:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] 281; CHECK-NEXT: store volatile float [[DENORMAL_1]], ptr addrspace(1) undef, align 4 282; CHECK-NEXT: ret void 283; 284 %zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0.0, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 285 store volatile float %zero, ptr addrspace(1) undef 286 287 %neg.zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float -0.0, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 288 store volatile float %neg.zero, ptr addrspace(1) undef 289 290 %one = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0.0, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 291 store volatile float %one, ptr addrspace(1) undef 292 293 %unknown.zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 294 store volatile float %unknown.zero, ptr addrspace(1) undef 295 296 %unknown.undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 297 store volatile float %unknown.undef, ptr addrspace(1) undef 298 299 %denormal.0 = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 300 store volatile float %denormal.0, ptr addrspace(1) undef 301 302 %denormal.1 = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 303 store volatile float %denormal.1, ptr addrspace(1) undef 304 305 ret void 306} 307 308define void @ldexp_f32() { 309; CHECK-LABEL: @ldexp_f32( 310; CHECK-NEXT: store volatile float 2.000000e+00, ptr addrspace(1) undef, align 4 311; CHECK-NEXT: store volatile float 4.000000e+00, ptr addrspace(1) undef, align 4 312; CHECK-NEXT: store volatile float 8.000000e+00, ptr addrspace(1) undef, align 4 313; CHECK-NEXT: store volatile float 5.000000e-01, ptr addrspace(1) undef, align 4 314; CHECK-NEXT: store volatile float 0x3810000000000000, ptr addrspace(1) undef, align 4 315; CHECK-NEXT: store volatile float 0x3800000000000000, ptr addrspace(1) undef, align 4 316; CHECK-NEXT: store volatile float 0x47E0000000000000, ptr addrspace(1) undef, align 4 317; CHECK-NEXT: store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4 318; CHECK-NEXT: store volatile float -2.000000e+00, ptr addrspace(1) undef, align 4 319; CHECK-NEXT: store volatile float -4.000000e+00, ptr addrspace(1) undef, align 4 320; CHECK-NEXT: store volatile float -8.000000e+00, ptr addrspace(1) undef, align 4 321; CHECK-NEXT: store volatile float -5.000000e-01, ptr addrspace(1) undef, align 4 322; CHECK-NEXT: store volatile float 0xB810000000000000, ptr addrspace(1) undef, align 4 323; CHECK-NEXT: store volatile float 0xB800000000000000, ptr addrspace(1) undef, align 4 324; CHECK-NEXT: store volatile float 0xC7E0000000000000, ptr addrspace(1) undef, align 4 325; CHECK-NEXT: store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4 326; CHECK-NEXT: store volatile float 0x44D5000000000000, ptr addrspace(1) undef, align 4 327; CHECK-NEXT: ret void 328; 329 %one.one = call float @llvm.ldexp.f32.i32(float 1.0, i32 1) 330 store volatile float %one.one, ptr addrspace(1) undef 331 332 %one.two = call float @llvm.ldexp.f32.i32(float 1.0, i32 2) 333 store volatile float %one.two, ptr addrspace(1) undef 334 335 %one.three = call float @llvm.ldexp.f32.i32(float 1.0, i32 3) 336 store volatile float %one.three, ptr addrspace(1) undef 337 338 %one.negone = call float @llvm.ldexp.f32.i32(float 1.0, i32 -1) 339 store volatile float %one.negone, ptr addrspace(1) undef 340 341 %one.min.exp = call float @llvm.ldexp.f32.i32(float 1.0, i32 -126) 342 store volatile float %one.min.exp, ptr addrspace(1) undef 343 344 %one.min.exp.sub1 = call float @llvm.ldexp.f32.i32(float 1.0, i32 -127) 345 store volatile float %one.min.exp.sub1, ptr addrspace(1) undef 346 347 %one.max.exp = call float @llvm.ldexp.f32.i32(float 1.0, i32 127) 348 store volatile float %one.max.exp, ptr addrspace(1) undef 349 350 %one.max.exp.plus1 = call float @llvm.ldexp.f32.i32(float 1.0, i32 128) 351 store volatile float %one.max.exp.plus1, ptr addrspace(1) undef 352 353 %neg.one.one = call float @llvm.ldexp.f32.i32(float -1.0, i32 1) 354 store volatile float %neg.one.one, ptr addrspace(1) undef 355 356 %neg.one.two = call float @llvm.ldexp.f32.i32(float -1.0, i32 2) 357 store volatile float %neg.one.two, ptr addrspace(1) undef 358 359 %neg.one.three = call float @llvm.ldexp.f32.i32(float -1.0, i32 3) 360 store volatile float %neg.one.three, ptr addrspace(1) undef 361 362 %neg.one.negone = call float @llvm.ldexp.f32.i32(float -1.0, i32 -1) 363 store volatile float %neg.one.negone, ptr addrspace(1) undef 364 365 %neg.one.min.exp = call float @llvm.ldexp.f32.i32(float -1.0, i32 -126) 366 store volatile float %neg.one.min.exp, ptr addrspace(1) undef 367 368 %neg.one.min.exp.sub1 = call float @llvm.ldexp.f32.i32(float -1.0, i32 -127) 369 store volatile float %neg.one.min.exp.sub1, ptr addrspace(1) undef 370 371 %neg.one.max.exp = call float @llvm.ldexp.f32.i32(float -1.0, i32 127) 372 store volatile float %neg.one.max.exp, ptr addrspace(1) undef 373 374 %neg.one.max.exp.plus1 = call float @llvm.ldexp.f32.i32(float -1.0, i32 128) 375 store volatile float %neg.one.max.exp.plus1, ptr addrspace(1) undef 376 377 %fortytwo.seven = call float @llvm.ldexp.f32.i32(float 42.0, i32 73) 378 store volatile float %fortytwo.seven, ptr addrspace(1) undef 379 380 ret void 381} 382 383; Technically we should probably flush these depending on the expected 384; denormal mode of the function, but no other IR constant folding 385; considers this. 386define void @ldexp_f32_denormal() { 387; CHECK-LABEL: @ldexp_f32_denormal( 388; CHECK-NEXT: store volatile float 0x380FFFFFC0000000, ptr addrspace(1) undef, align 4 389; CHECK-NEXT: store volatile float 0x381FFFFFC0000000, ptr addrspace(1) undef, align 4 390; CHECK-NEXT: ret void 391; 392 %denormal.0 = call float @llvm.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0) 393 store volatile float %denormal.0, ptr addrspace(1) undef 394 395 %denormal.1 = call float @llvm.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1) 396 store volatile float %denormal.1, ptr addrspace(1) undef 397 398 ret void 399} 400 401define void @ldexp_f64() { 402; CHECK-LABEL: @ldexp_f64( 403; CHECK-NEXT: store volatile double 2.000000e+00, ptr addrspace(1) undef, align 8 404; CHECK-NEXT: store volatile double 4.000000e+00, ptr addrspace(1) undef, align 8 405; CHECK-NEXT: store volatile double 0x44D5000000000000, ptr addrspace(1) undef, align 8 406; CHECK-NEXT: ret void 407; 408 %one.one = call double @llvm.ldexp.f64.i32(double 1.0, i32 1) 409 store volatile double %one.one, ptr addrspace(1) undef 410 411 %one.two = call double @llvm.ldexp.f64.i32(double 1.0, i32 2) 412 store volatile double %one.two, ptr addrspace(1) undef 413 414 %fortytwo.seven = call double @llvm.ldexp.f64.i32(double 42.0, i32 73) 415 store volatile double %fortytwo.seven, ptr addrspace(1) undef 416 417 ret void 418} 419 420define void @ldexp_f16() { 421; CHECK-LABEL: @ldexp_f16( 422; CHECK-NEXT: store volatile half 0xH4000, ptr addrspace(1) undef, align 2 423; CHECK-NEXT: store volatile half 0xH4400, ptr addrspace(1) undef, align 2 424; CHECK-NEXT: store volatile half 0xH7C00, ptr addrspace(1) undef, align 2 425; CHECK-NEXT: ret void 426; 427 %one.one = call half @llvm.ldexp.f16.i32(half 1.0, i32 1) 428 store volatile half %one.one, ptr addrspace(1) undef 429 430 %one.two = call half @llvm.ldexp.f16.i32(half 1.0, i32 2) 431 store volatile half %one.two, ptr addrspace(1) undef 432 433 %fortytwo.seven = call half @llvm.ldexp.f16.i32(half 42.0, i32 73) 434 store volatile half %fortytwo.seven, ptr addrspace(1) undef 435 436 ret void 437} 438 439define void @ldexp_ppcf128() { 440; CHECK-LABEL: @ldexp_ppcf128( 441; CHECK-NEXT: store volatile ppc_fp128 0xMFFF00000000000000000000000000000, ptr addrspace(1) undef, align 16 442; CHECK-NEXT: store volatile ppc_fp128 0xMFFFC0000000000000000000000000000, ptr addrspace(1) undef, align 16 443; CHECK-NEXT: store volatile ppc_fp128 0xM3FD00000000000000000000000000000, ptr addrspace(1) undef, align 16 444; CHECK-NEXT: store volatile ppc_fp128 0xM41700000000000000000000000000000, ptr addrspace(1) undef, align 16 445; CHECK-NEXT: store volatile ppc_fp128 0xMC0700000000000000000000000000000, ptr addrspace(1) undef, align 16 446; CHECK-NEXT: ret void 447; 448 %neginf = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMFFF00000000000000000000000000000, i32 0) 449 store volatile ppc_fp128 %neginf, ptr addrspace(1) undef 450 451 %snan = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMFFFC0000000000000000000000000000, i32 0) 452 store volatile ppc_fp128 %snan, ptr addrspace(1) undef 453 454 %one.neg2 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000, i32 -2) 455 store volatile ppc_fp128 %one.neg2, ptr addrspace(1) undef 456 457 %one.24 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000, i32 24) 458 store volatile ppc_fp128 %one.24, ptr addrspace(1) undef 459 460 %negone.8 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMBFF00000000000000000000000000000, i32 8) 461 store volatile ppc_fp128 %negone.8, ptr addrspace(1) undef 462 463 ret void 464} 465 466define void @constant_fold_ldexp_f32_val_strictfp(i32 %y) #0 { 467; CHECK-LABEL: @constant_fold_ldexp_f32_val_strictfp( 468; CHECK-NEXT: [[SNAN_MAY_TRAP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]] 469; CHECK-NEXT: store volatile float [[SNAN_MAY_TRAP]], ptr addrspace(1) undef, align 4 470; CHECK-NEXT: [[SNAN_MAY_NOT_TRAP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]] 471; CHECK-NEXT: store volatile float [[SNAN_MAY_NOT_TRAP]], ptr addrspace(1) undef, align 4 472; CHECK-NEXT: [[UNKNOWN_ROUNDING:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]] 473; CHECK-NEXT: store volatile float [[UNKNOWN_ROUNDING]], ptr addrspace(1) undef, align 4 474; CHECK-NEXT: [[NORMAL:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]] 475; CHECK-NEXT: store volatile float [[NORMAL]], ptr addrspace(1) undef, align 4 476; CHECK-NEXT: [[NORMAL_DOWN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]] 477; CHECK-NEXT: store volatile float [[NORMAL_DOWN]], ptr addrspace(1) undef, align 4 478; CHECK-NEXT: ret void 479; 480 %snan.may.trap = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0 481 store volatile float %snan.may.trap, ptr addrspace(1) undef 482 483 %snan.may.not.trap = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0 484 store volatile float %snan.may.not.trap, ptr addrspace(1) undef 485 486 %unknown.rounding = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 487 store volatile float %unknown.rounding, ptr addrspace(1) undef 488 489 %normal = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0 490 store volatile float %normal, ptr addrspace(1) undef 491 492 %normal.down = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.downward", metadata !"fpexcept.ignore") #0 493 store volatile float %normal.down, ptr addrspace(1) undef 494 495 ret void 496} 497 498declare half @llvm.ldexp.f16.i32(half, i32) #1 499declare float @llvm.ldexp.f32.i32(float, i32) #1 500declare double @llvm.ldexp.f64.i32(double, i32) #1 501declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #1 502declare float @llvm.experimental.constrained.ldexp.f32.i32(float, i32, metadata, metadata) #1 503declare ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128, i32) #1 504 505attributes #0 = { strictfp } 506attributes #1 = { nounwind readnone speculatable } 507