; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s ; select c, (ldexp val, e0), (ldexp val, e1) -> ldexp val, (select c, e0, e1) define float @select_ldexp_f32_sameval_differentexp(i1 %cond, float %val, i32 %exp0, i32 %exp1) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_selectflags(i1 %cond, float %val, i32 %exp0, i32 %exp1) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_selectflags ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1) %select = select nnan i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags(i1 %cond, float %val, i32 %exp0, i32 %exp1) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val, i32 %exp0) %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val, i32 %exp1) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags_union_select(i1 %cond, float %val, i32 %exp0, i32 %exp1) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags_union_select ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val, i32 %exp0) %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val, i32 %exp1) %select = select ninf i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_multiuse0(i1 %cond, float %val, i32 %exp0, i32 %exp1, ptr %ptr) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_multiuse0 ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP0]]) ; CHECK-NEXT: store float [[LDEXP0]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0) store float %ldexp0, ptr %ptr %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_multiuse1(i1 %cond, float %val, i32 %exp0, i32 %exp1, ptr %ptr) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_multiuse1 ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP1]]) ; CHECK-NEXT: store float [[LDEXP1]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1) store float %ldexp1, ptr %ptr %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_multiuse_both(i1 %cond, float %val, i32 %exp0, i32 %exp1, ptr %ptr0, ptr %ptr1) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_multiuse_both ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP0]]) ; CHECK-NEXT: store float [[LDEXP0]], ptr [[PTR0]], align 4 ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP1]]) ; CHECK-NEXT: store float [[LDEXP1]], ptr [[PTR1]], align 4 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[LDEXP0]], float [[LDEXP1]] ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0) store float %ldexp0, ptr %ptr0 %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1) store float %ldexp1, ptr %ptr1 %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } ; select c, (ldexp val0, e), (ldexp val1, ee) -> ldexp (select c, val0, val1), e define float @select_ldexp_f32_differentval_sameexp(i1 %cond, float %val0, float %val1, i32 %exp) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_sameexp_selectflags(i1 %cond, float %val0, float %val1, i32 %exp) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_selectflags ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp) %select = select nnan i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags(i1 %cond, float %val0, float %val1, i32 %exp) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val0, i32 %exp) %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val1, i32 %exp) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags_unino_select(i1 %cond, float %val0, float %val1, i32 %exp) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags_unino_select ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val0, i32 %exp) %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val1, i32 %exp) %select = select ninf i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_sameexp_multiuse0(i1 %cond, float %val0, float %val1, i32 %exp, ptr %ptr) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_multiuse0 ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL0]], i32 [[EXP]]) ; CHECK-NEXT: store float [[LDEXP0]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp) store float %ldexp0, ptr %ptr %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_sameexp_multiuse1(i1 %cond, float %val0, float %val1, i32 %exp, ptr %ptr) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_multiuse1 ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL1]], i32 [[EXP]]) ; CHECK-NEXT: store float [[LDEXP1]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp) store float %ldexp1, ptr %ptr %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_differentexp(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[TMP2]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_differentexp_multiuse0(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1, ptr %ptr) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp_multiuse0 ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL0]], i32 [[EXP0]]) ; CHECK-NEXT: store float [[LDEXP0]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[TMP2]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0) store float %ldexp0, ptr %ptr %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_differentexp_multiuse1(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1, ptr %ptr) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp_multiuse1 ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL1]], i32 [[EXP1]]) ; CHECK-NEXT: store float [[LDEXP1]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[TMP2]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1) store float %ldexp1, ptr %ptr %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_differentval_differentexp_multiuse_both(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1, ptr %ptr0, ptr %ptr1) { ; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp_multiuse_both ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL0]], i32 [[EXP0]]) ; CHECK-NEXT: store float [[LDEXP0]], ptr [[PTR0]], align 4 ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL1]], i32 [[EXP1]]) ; CHECK-NEXT: store float [[LDEXP1]], ptr [[PTR1]], align 4 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[LDEXP0]], float [[LDEXP1]] ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0) store float %ldexp0, ptr %ptr0 %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1) store float %ldexp1, ptr %ptr1 %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define <2 x float> @select_ldexp_v2f32_sameval_differentexp(<2 x i1> %cond, <2 x float> %val, <2 x i32> %exp0, <2 x i32> %exp1) { ; CHECK-LABEL: define <2 x float> @select_ldexp_v2f32_sameval_differentexp ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[VAL:%.*]], <2 x i32> [[EXP0:%.*]], <2 x i32> [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[EXP0]], <2 x i32> [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[VAL]], <2 x i32> [[TMP1]]) ; CHECK-NEXT: ret <2 x float> [[SELECT]] ; %ldexp0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp0) %ldexp1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp1) %select = select <2 x i1> %cond, <2 x float> %ldexp0, <2 x float> %ldexp1 ret <2 x float> %select } define <2 x float> @select_ldexp_v2f32_differentval_sameexp(<2 x i1> %cond, <2 x float> %val0, <2 x float> %val1, <2 x i32> %exp) { ; CHECK-LABEL: define <2 x float> @select_ldexp_v2f32_differentval_sameexp ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[VAL0:%.*]], <2 x float> [[VAL1:%.*]], <2 x i32> [[EXP:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[COND]], <2 x float> [[VAL0]], <2 x float> [[VAL1]] ; CHECK-NEXT: [[SELECT:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[TMP1]], <2 x i32> [[EXP]]) ; CHECK-NEXT: ret <2 x float> [[SELECT]] ; %ldexp0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val0, <2 x i32> %exp) %ldexp1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val1, <2 x i32> %exp) %select = select <2 x i1> %cond, <2 x float> %ldexp0, <2 x float> %ldexp1 ret <2 x float> %select } define <2 x float> @select_ldexp_v2f32_differentval_differentexp(<2 x i1> %cond, <2 x float> %val0, <2 x float> %val1, <2 x i32> %exp0, <2 x i32> %exp1) { ; CHECK-LABEL: define <2 x float> @select_ldexp_v2f32_differentval_differentexp ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[VAL0:%.*]], <2 x float> [[VAL1:%.*]], <2 x i32> [[EXP0:%.*]], <2 x i32> [[EXP1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[COND]], <2 x float> [[VAL0]], <2 x float> [[VAL1]] ; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[EXP0]], <2 x i32> [[EXP1]] ; CHECK-NEXT: [[SELECT:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[TMP1]], <2 x i32> [[TMP2]]) ; CHECK-NEXT: ret <2 x float> [[SELECT]] ; %ldexp0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val0, <2 x i32> %exp0) %ldexp1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val1, <2 x i32> %exp1) %select = select <2 x i1> %cond, <2 x float> %ldexp0, <2 x float> %ldexp1 ret <2 x float> %select } define float @select_ldexp_f32_same(i1 %cond, float %val, i32 %exp) { ; CHECK-LABEL: define float @select_ldexp_f32_same ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp) %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } define float @select_ldexp_f32_sameval_differentexp_types(i1 %cond, float %val, i32 %exp0, i64 %exp1) { ; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_types ; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i64 [[EXP1:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP0]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i64(float [[VAL]], i64 [[EXP1]]) ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[LDEXP0]], float [[LDEXP1]] ; CHECK-NEXT: ret float [[SELECT]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0) %ldexp1 = call float @llvm.ldexp.f32.i64(float %val, i64 %exp1) %select = select i1 %cond, float %ldexp0, float %ldexp1 ret float %select } ;--------------------------------------------------------------------- ; ldexp(ldexp(x, a), b) -> ldexp(x, a + b) ;--------------------------------------------------------------------- define float @ldexp_ldexp(float %x, i32 %a, i32 %b) { ; CHECK-LABEL: define float @ldexp_ldexp ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_reassoc_ldexp(float %x, i32 %a, i32 %b) { ; CHECK-LABEL: define float @ldexp_reassoc_ldexp ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_ldexp_reassoc(float %x, i32 %a, i32 %b) { ; CHECK-LABEL: define float @ldexp_ldexp_reassoc ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_reassoc_ldexp_reassoc(float %x, i32 %a, i32 %b) { ; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_reassoc_nsz_ldexp_reassoc_nsz(float %x, i32 %a, i32 %b) { ; CHECK-LABEL: define float @ldexp_reassoc_nsz_ldexp_reassoc_nsz ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call reassoc nsz float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } ; Test that we or the inner and outer flags define float @ldexp_reassoc_ldexp_reassoc_preserve_flags(float %x, i32 %a, i32 %b) { ; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc_preserve_flags ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nnan ninf float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc ninf float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call reassoc nnan float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define <2 x float> @ldexp_reassoc_ldexp_reassoc_vec(<2 x float> %x, <2 x i32> %a, <2 x i32> %b) { ; CHECK-LABEL: define <2 x float> @ldexp_reassoc_ldexp_reassoc_vec ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> [[A]], <2 x i32> [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[TMP1]]) ; CHECK-NEXT: ret <2 x float> [[LDEXP1]] ; %ldexp0 = call reassoc <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %a) %ldexp1 = call reassoc <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %ldexp0, <2 x i32> %b) ret <2 x float> %ldexp1 } define float @ldexp_reassoc_ldexp_reassoc_i8_exp_not_safe(float %x, i8 %a, i8 %b) { ; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc_i8_exp_not_safe ; CHECK-SAME: (float [[X:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i8(float [[X]], i8 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i8(float [[LDEXP0]], i8 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i8(float %x, i8 %a) %ldexp1 = call reassoc float @llvm.ldexp.f32.i8(float %ldexp0, i8 %b) ret float %ldexp1 } define float @ldexp_reassoc_ldexp_reassoc_i64_exp_safe(float %x, i64 %a, i64 %b) { ; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc_i64_exp_safe ; CHECK-SAME: (float [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.sadd.sat.i64(i64 [[A]], i64 [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i64(float [[X]], i64 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i64(float %x, i64 %a) %ldexp1 = call reassoc float @llvm.ldexp.f32.i64(float %ldexp0, i64 %b) ret float %ldexp1 } define half @ldexp_reassoc_ldexp_reassoc_f16_i8_exp_safe(half %x, i8 %a, i8 %b) { ; CHECK-LABEL: define half @ldexp_reassoc_ldexp_reassoc_f16_i8_exp_safe ; CHECK-SAME: (half [[X:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A]], i8 [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc half @llvm.ldexp.f16.i8(half [[X]], i8 [[TMP1]]) ; CHECK-NEXT: ret half [[LDEXP1]] ; %ldexp0 = call reassoc half @llvm.ldexp.f16.i8(half %x, i8 %a) %ldexp1 = call reassoc half @llvm.ldexp.f16.i8(half %ldexp0, i8 %b) ret half %ldexp1 } define ppc_fp128 @ldexp_reassoc_ldexp_reassoc_ppcf128(ppc_fp128 %x, i32 %a, i32 %b) { ; CHECK-LABEL: define ppc_fp128 @ldexp_reassoc_ldexp_reassoc_ppcf128 ; CHECK-SAME: (ppc_fp128 [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret ppc_fp128 [[LDEXP1]] ; %ldexp0 = call reassoc ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 %x, i32 %a) %ldexp1 = call reassoc ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 %ldexp0, i32 %b) ret ppc_fp128 %ldexp1 } define float @ldexp_multi_use_ldexp(float %x, i32 %a, i32 %b, ptr %ptr) { ; CHECK-LABEL: define float @ldexp_multi_use_ldexp ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: store float [[LDEXP0]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a) store float %ldexp0, ptr %ptr %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } ; Test edge case where the intrinsic is declared with different int types. define float @ldexp_ldexp_different_exp_type(float %x, i32 %a, i64 %b) { ; CHECK-LABEL: define float @ldexp_ldexp_different_exp_type ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i64(float [[LDEXP0]], i64 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call reassoc float @llvm.ldexp.f32.i64(float %ldexp0, i64 %b) ret float %ldexp1 } define float @ldexp_ldexp_constants(float %x) { ; CHECK-LABEL: define float @ldexp_ldexp_constants ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc float [[X]], f0x4F800000 ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 24) ret float %ldexp1 } define float @ldexp_ldexp_constants_nsz(float %x) { ; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc nsz float [[X]], f0x4F800000 ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 8) %ldexp1 = call reassoc nsz float @llvm.ldexp.f32.i32(float %ldexp0, i32 24) ret float %ldexp1 } define float @ldexp_ldexp_constants_nsz0(float %x) { ; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz0 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc float [[X]], f0x4F800000 ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 8) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 24) ret float %ldexp1 } define float @ldexp_ldexp_constants_nsz1(float %x) { ; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz1 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc nsz float [[X]], f0x4F800000 ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8) %ldexp1 = call reassoc nsz float @llvm.ldexp.f32.i32(float %ldexp0, i32 24) ret float %ldexp1 } define float @ldexp_ldexp_opposite_constants(float %x) { ; CHECK-LABEL: define float @ldexp_ldexp_opposite_constants ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: ret float [[X]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 -8) ret float %ldexp1 } define float @ldexp_ldexp_negated_variable_reassoc(float %x, i32 %a) { ; CHECK-LABEL: define float @ldexp_ldexp_negated_variable_reassoc ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]]) { ; CHECK-NEXT: [[NEG_A:%.*]] = sub i32 0, [[A]] ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 [[NEG_A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a) %neg.a = sub i32 0, %a %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %neg.a) ret float %ldexp1 } define float @ldexp_ldexp_intmin_intmin_reassoc(float %x) { ; CHECK-LABEL: define float @ldexp_ldexp_intmin_intmin_reassoc ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 -2147483648) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 -2147483648) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 -2147483648) ret float %ldexp1 } define float @ldexp_ldexp_negated_variable(float %x, i32 %a) { ; CHECK-LABEL: define float @ldexp_ldexp_negated_variable ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]]) { ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[NEG_A:%.*]] = sub i32 0, [[A]] ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[NEG_A]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %neg.a = sub i32 0, %a %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %neg.a) ret float %ldexp1 } define float @ldexp_ldexp_first_exp_known_positive(float %x, i32 %a.arg, i32 %b) { ; CHECK-LABEL: define float @ldexp_ldexp_first_exp_known_positive ; CHECK-SAME: (float [[X:%.*]], i32 [[A_ARG:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = and i32 [[A_ARG]], 127 ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %a = and i32 %a.arg, 127 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_ldexp_first_second_known_positive(float %x, i32 %a, i32 %b.arg) { ; CHECK-LABEL: define float @ldexp_ldexp_first_second_known_positive ; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B_ARG:%.*]]) { ; CHECK-NEXT: [[B:%.*]] = and i32 [[B_ARG]], 127 ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %b = and i32 %b.arg, 127 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_ldexp_both_exp_known_positive(float %x, i32 %a.arg, i32 %b.arg) { ; CHECK-LABEL: define float @ldexp_ldexp_both_exp_known_positive ; CHECK-SAME: (float [[X:%.*]], i32 [[A_ARG:%.*]], i32 [[B_ARG:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = and i32 [[A_ARG]], 127 ; CHECK-NEXT: [[B:%.*]] = and i32 [[B_ARG]], 127 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A]], [[B]] ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %a = and i32 %a.arg, 127 %b = and i32 %b.arg, 127 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_ldexp_both_exp_known_negative(float %x, ptr %a.ptr, ptr %b.ptr) { ; CHECK-LABEL: define float @ldexp_ldexp_both_exp_known_negative ; CHECK-SAME: (float [[X:%.*]], ptr [[A_PTR:%.*]], ptr [[B_PTR:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[A_PTR]], align 4, !range [[RNG0:![0-9]+]] ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[B_PTR]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[A]], [[B]] ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %a = load i32, ptr %a.ptr, !range !0 %b = load i32, ptr %b.ptr, !range !0 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_ldexp_exp_known_negative_and_positive(float %x, ptr %a.ptr, ptr %b.ptr) { ; CHECK-LABEL: define float @ldexp_ldexp_exp_known_negative_and_positive ; CHECK-SAME: (float [[X:%.*]], ptr [[A_PTR:%.*]], ptr [[B_PTR:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[A_PTR]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[B_PTR]], align 4, !range [[RNG1:![0-9]+]] ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %a = load i32, ptr %a.ptr, !range !0 %b = load i32, ptr %b.ptr, !range !1 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_ldexp_exp_known_positive_and_negative(float %x, ptr %a.ptr, ptr %b.ptr) { ; CHECK-LABEL: define float @ldexp_ldexp_exp_known_positive_and_negative ; CHECK-SAME: (float [[X:%.*]], ptr [[A_PTR:%.*]], ptr [[B_PTR:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[A_PTR]], align 4, !range [[RNG1]] ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[B_PTR]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]]) ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %a = load i32, ptr %a.ptr, !range !1 %b = load i32, ptr %b.ptr, !range !0 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b) ret float %ldexp1 } define float @ldexp_reassoc_ldexp_reassoc_0(float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc_0 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 0) %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %y) ret float %ldexp1 } define float @ldexp_ldexp_0(float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_ldexp_0 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]]) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 0) %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %y) ret float %ldexp1 } ;--------------------------------------------------------------------- ; ldexp(x, k) -> fmul x, 2**k ;--------------------------------------------------------------------- define float @ldexp_neg150(float %x) { ; CHECK-LABEL: define float @ldexp_neg150 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -150) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -150) ret float %ldexp } define float @ldexp_neg149(float %x) { ; CHECK-LABEL: define float @ldexp_neg149 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 1.401300e-45 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -149) ret float %ldexp } define float @ldexp_neg148(float %x) { ; CHECK-LABEL: define float @ldexp_neg148 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 2.802600e-45 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -148) ret float %ldexp } define float @ldexp_neg127(float %x) { ; CHECK-LABEL: define float @ldexp_neg127 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x00400000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -127) ret float %ldexp } define float @ldexp_neg126(float %x) { ; CHECK-LABEL: define float @ldexp_neg126 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x00800000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -126) ret float %ldexp } define float @ldexp_neg125(float %x) { ; CHECK-LABEL: define float @ldexp_neg125 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x01000000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -125) ret float %ldexp } define float @ldexp_neg16(float %x) { ; CHECK-LABEL: define float @ldexp_neg16 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x37800000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -16) ret float %ldexp } define float @ldexp_neg8(float %x) { ; CHECK-LABEL: define float @ldexp_neg8 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 3.906250e-03 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -8) ret float %ldexp } define float @ldexp_neg4(float %x) { ; CHECK-LABEL: define float @ldexp_neg4 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 6.250000e-02 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -4) ret float %ldexp } define float @ldexp_neg2(float %x) { ; CHECK-LABEL: define float @ldexp_neg2 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 2.500000e-01 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -2) ret float %ldexp } define float @ldexp_neg1(float %x) { ; CHECK-LABEL: define float @ldexp_neg1 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 5.000000e-01 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -1) ret float %ldexp } define float @ldexp_0(float %x) { ; CHECK-LABEL: define float @ldexp_0 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: ret float [[X]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 0) ret float %ldexp } define float @ldexp_1(float %x) { ; CHECK-LABEL: define float @ldexp_1 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 2.000000e+00 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 1) ret float %ldexp } define float @ldexp_2(float %x) { ; CHECK-LABEL: define float @ldexp_2 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 4.000000e+00 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2) ret float %ldexp } define float @ldexp_3(float %x) { ; CHECK-LABEL: define float @ldexp_3 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 8.000000e+00 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 3) ret float %ldexp } define float @ldexp_10(float %x) { ; CHECK-LABEL: define float @ldexp_10 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 1.024000e+03 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 10) ret float %ldexp } define float @ldexp_125(float %x) { ; CHECK-LABEL: define float @ldexp_125 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x7E000000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 125) ret float %ldexp } define float @ldexp_126(float %x) { ; CHECK-LABEL: define float @ldexp_126 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x7E800000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 126) ret float %ldexp } define float @ldexp_127(float %x) { ; CHECK-LABEL: define float @ldexp_127 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], f0x7F000000 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 127) ret float %ldexp } define float @ldexp_128(float %x) { ; CHECK-LABEL: define float @ldexp_128 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 128) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 128) ret float %ldexp } define float @ldexp_254(float %x) { ; CHECK-LABEL: define float @ldexp_254 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 254) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 254) ret float %ldexp } define float @ldexp_255(float %x) { ; CHECK-LABEL: define float @ldexp_255 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 255) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 255) ret float %ldexp } define float @ldexp_256(float %x) { ; CHECK-LABEL: define float @ldexp_256 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 256) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 256) ret float %ldexp } define float @ldexp_neg254(float %x) { ; CHECK-LABEL: define float @ldexp_neg254 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -254) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -254) ret float %ldexp } define float @ldexp_neg255(float %x) { ; CHECK-LABEL: define float @ldexp_neg255 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -255) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -255) ret float %ldexp } define float @ldexp_neg256(float %x) { ; CHECK-LABEL: define float @ldexp_neg256 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -256) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -256) ret float %ldexp } define float @ldexp_neg260(float %x) { ; CHECK-LABEL: define float @ldexp_neg260 ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -260) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -260) ret float %ldexp } define <2 x float> @ldexp_3_vector(<2 x float> %x) { ; CHECK-LABEL: define <2 x float> @ldexp_3_vector ; CHECK-SAME: (<2 x float> [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul <2 x float> [[X]], splat (float 8.000000e+00) ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> ) ret <2 x float> %ldexp } define <2 x float> @ldexp_3_undef_vector(<2 x float> %x) { ; CHECK-LABEL: define <2 x float> @ldexp_3_undef_vector ; CHECK-SAME: (<2 x float> [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> ) ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> ) ret <2 x float> %ldexp } define <2 x float> @ldexp_3_4_vector(<2 x float> %x) { ; CHECK-LABEL: define <2 x float> @ldexp_3_4_vector ; CHECK-SAME: (<2 x float> [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> ) ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> ) ret <2 x float> %ldexp } define float @ldexp_2_flags(float %x) { ; CHECK-LABEL: define float @ldexp_2_flags ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul nsz contract float [[X]], 4.000000e+00 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call contract nsz float @llvm.ldexp.f32.i32(float %x, i32 2) ret float %ldexp } define float @ldexp_metadata(float %x) { ; CHECK-LABEL: define float @ldexp_metadata ; CHECK-SAME: (float [[X:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 4.000000e+00 ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2), !foo !2 ret float %ldexp } define float @ldexp_8_contractable(float %x, float %y) { ; CHECK-LABEL: define float @ldexp_8_contractable ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = fmul contract float [[X]], 4.000000e+00 ; CHECK-NEXT: [[FADD:%.*]] = fadd contract float [[LDEXP]], [[Y]] ; CHECK-NEXT: ret float [[FADD]] ; %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 2) %fadd = fadd contract float %ldexp, %y ret float %fadd } define float @ldexp_f32_mask_select_0(i1 %cond, float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_f32_mask_select_0 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]]) ; CHECK-NEXT: [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]] ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 %y, i32 0 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_nnan_f32_mask_select_0(i1 %cond, float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_nnan_f32_mask_select_0 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]]) ; CHECK-NEXT: [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]] ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 %y, i32 0 %ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_flags_f32_mask_select_0(i1 %cond, float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_flags_f32_mask_select_0 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call ninf nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]]) ; CHECK-NEXT: [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]] ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 %y, i32 0 %ldexp = call nsz ninf float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_f32_mask_select_0_swap(i1 %cond, float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]]) ; CHECK-NEXT: [[LDEXP:%.*]] = select i1 [[COND]], float [[X]], float [[TMP1]] ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 0, i32 %y %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_f32_mask_select_1(i1 %cond, float %x, i32 %y) { ; CHECK-LABEL: define float @ldexp_f32_mask_select_1 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 1 ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 %y, i32 1 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_f32_mask_select_0_multi_use(i1 %cond, float %x, i32 %y, ptr %ptr) { ; CHECK-LABEL: define float @ldexp_f32_mask_select_0_multi_use ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0 ; CHECK-NEXT: store i32 [[SELECT]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 %y, i32 0 store i32 %select, ptr %ptr %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_f32_mask_select_0_swap_multi_use(i1 %cond, float %x, i32 %y, ptr %ptr) { ; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap_multi_use ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], i32 0, i32 [[Y]] ; CHECK-NEXT: store i32 [[SELECT]], ptr [[PTR]], align 4 ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 0, i32 %y store i32 %select, ptr %ptr %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select) ret float %ldexp } define float @ldexp_f32_mask_select_0_strictfp(i1 %cond, float %x, i32 %y) #0 { ; CHECK-LABEL: define float @ldexp_f32_mask_select_0_strictfp ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0 ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X]], i32 [[SELECT]], metadata !"round.dynamic", metadata !"fpexcept.strict") ; CHECK-NEXT: ret float [[LDEXP]] ; %select = select i1 %cond, i32 %y, i32 0 %ldexp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 %select, metadata !"round.dynamic", metadata !"fpexcept.strict") ret float %ldexp } define <2 x float> @ldexp_v2f32_mask_select_0(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0 ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[Y]]) ; CHECK-NEXT: [[LDEXP:%.*]] = select <2 x i1> [[COND]], <2 x float> [[TMP1]], <2 x float> [[X]] ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %select = select <2 x i1> %cond, <2 x i32> %y, <2 x i32> zeroinitializer %ldexp = call nsz nnan <2 x float> @llvm.ldexp.f32.v2i32(<2 x float> %x, <2 x i32> %select) ret <2 x float> %ldexp } define <2 x float> @ldexp_v2f32_mask_select_0_swap(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0_swap ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[Y]]) ; CHECK-NEXT: [[LDEXP:%.*]] = select <2 x i1> [[COND]], <2 x float> [[X]], <2 x float> [[TMP1]] ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %select = select <2 x i1> %cond, <2 x i32> zeroinitializer, <2 x i32> %y %ldexp = call nsz nnan <2 x float> @llvm.ldexp.f32.v2i32(<2 x float> %x, <2 x i32> %select) ret <2 x float> %ldexp } ; Exponent constants that exceed `int` saturate to +/-inf / +/-0 rather than ; silently narrowing. define double @ldexp_i64_exp_above_int_max() { ; CHECK-LABEL: define double @ldexp_i64_exp_above_int_max() { ; CHECK-NEXT: ret double +inf ; %r = call double @llvm.ldexp.f64.i64(double 1.0, i64 4294967330) ret double %r } define double @ldexp_i64_exp_below_int_min() { ; CHECK-LABEL: define double @ldexp_i64_exp_below_int_min() { ; CHECK-NEXT: ret double 0.000000e+00 ; %r = call double @llvm.ldexp.f64.i64(double 1.0, i64 -4294967330) ret double %r } define double @ldexp_i64_neg_input_exp_above_int_max() { ; CHECK-LABEL: define double @ldexp_i64_neg_input_exp_above_int_max() { ; CHECK-NEXT: ret double -inf ; %r = call double @llvm.ldexp.f64.i64(double -1.0, i64 4294967330) ret double %r } define double @ldexp_i64_neg_input_exp_above_int64_max() { ; CHECK-LABEL: define double @ldexp_i64_neg_input_exp_above_int64_max() { ; CHECK-NEXT: ret double -inf ; ; This constant is 2^65, i.e. it exceeds the range of i64. %r = call double @llvm.ldexp.f64.i128(double -1.0, i128 36893488147419103232) ret double %r } define double @ldexp_i16_exp_narrow_int() { ; CHECK-LABEL: define double @ldexp_i16_exp_narrow_int() { ; CHECK-NEXT: ret double 4.096000e+03 ; %r = call double @llvm.ldexp.f64.i16(double 1.0, i16 12) ret double %r } define double @ldexp_i16_exp_narrow_int_negative() { ; CHECK-LABEL: define double @ldexp_i16_exp_narrow_int_negative() { ; CHECK-NEXT: ret double 4.000000e+00 ; %r = call double @llvm.ldexp.f64.i16(double 8.0, i16 -1) ret double %r } attributes #0 = { strictfp } !0 = !{i32 -127, i32 0} !1 = !{i32 0, i32 127} !2 = !{}