CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
688 lines
27 KiB
LLVM
688 lines
27 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
|
|
|
|
declare void @use(i32)
|
|
declare void @usef32(float)
|
|
|
|
declare i32 @llvm.ctlz.i32(i32, i1)
|
|
declare <3 x i17> @llvm.ctlz.v3i17(<3 x i17>, i1)
|
|
|
|
declare i32 @llvm.cttz.i32(i32, i1)
|
|
declare <3 x i5> @llvm.cttz.v3i5(<3 x i5>, i1)
|
|
|
|
declare i32 @llvm.ctpop.i32(i32)
|
|
declare <3 x i7> @llvm.ctpop.v3i7(<3 x i7>)
|
|
|
|
declare i32 @llvm.usub.sat.i32(i32, i32)
|
|
|
|
define i32 @ctlz_sel_const_true_false(i1 %b) {
|
|
; CHECK-LABEL: @ctlz_sel_const_true_false(
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 29, i32 0
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 -7
|
|
%c = call i32 @llvm.ctlz.i32(i32 %s, i1 true)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @ctlz_sel_const_true(i1 %b, i32 %x) {
|
|
; CHECK-LABEL: @ctlz_sel_const_true(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 29, i32 [[TMP1]]
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 %x
|
|
%c = call i32 @llvm.ctlz.i32(i32 %s, i1 false)
|
|
ret i32 %c
|
|
}
|
|
|
|
define <3 x i17> @ctlz_sel_const_false(<3 x i1> %b, <3 x i17> %x) {
|
|
; CHECK-LABEL: @ctlz_sel_const_false(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call range(i17 0, 18) <3 x i17> @llvm.ctlz.v3i17(<3 x i17> [[X:%.*]], i1 true)
|
|
; CHECK-NEXT: [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i17> [[TMP1]], <3 x i17> <i17 14, i17 0, i17 poison>
|
|
; CHECK-NEXT: ret <3 x i17> [[C]]
|
|
;
|
|
%s = select <3 x i1> %b, <3 x i17> %x, <3 x i17> <i17 7, i17 -1, i17 0>
|
|
%c = call <3 x i17> @llvm.ctlz.v3i17(<3 x i17> %s, i1 true)
|
|
ret <3 x i17> %c
|
|
}
|
|
|
|
define i32 @ctlz_sel_const_true_false_extra_use(i1 %b) {
|
|
; CHECK-LABEL: @ctlz_sel_const_true_false_extra_use(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 -1, i32 7
|
|
; CHECK-NEXT: call void @use(i32 [[S]])
|
|
; CHECK-NEXT: [[C:%.*]] = call range(i32 0, 30) i32 @llvm.ctlz.i32(i32 [[S]], i1 true)
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 -1, i32 7
|
|
call void @use(i32 %s)
|
|
%c = call i32 @llvm.ctlz.i32(i32 %s, i1 false)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @cttz_sel_const_true_false(i1 %b) {
|
|
; CHECK-LABEL: @cttz_sel_const_true_false(
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 0
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 4, i32 -7
|
|
%c = call i32 @llvm.cttz.i32(i32 %s, i1 false)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @cttz_sel_const_true(i1 %b, i32 %x) {
|
|
; CHECK-LABEL: @cttz_sel_const_true(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 0, i32 [[TMP1]]
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 %x
|
|
%c = call i32 @llvm.cttz.i32(i32 %s, i1 true)
|
|
ret i32 %c
|
|
}
|
|
|
|
define <3 x i5> @cttz_sel_const_false(<3 x i1> %b, <3 x i5> %x) {
|
|
; CHECK-LABEL: @cttz_sel_const_false(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call range(i5 0, 6) <3 x i5> @llvm.cttz.v3i5(<3 x i5> [[X:%.*]], i1 false)
|
|
; CHECK-NEXT: [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i5> [[TMP1]], <3 x i5> <i5 0, i5 0, i5 5>
|
|
; CHECK-NEXT: ret <3 x i5> [[C]]
|
|
;
|
|
%s = select <3 x i1> %b, <3 x i5> %x, <3 x i5> <i5 7, i5 -1, i5 0>
|
|
%c = call <3 x i5> @llvm.cttz.v3i5(<3 x i5> %s, i1 false)
|
|
ret <3 x i5> %c
|
|
}
|
|
|
|
define i32 @cttz_sel_const_true_false_extra_use(i1 %b) {
|
|
; CHECK-LABEL: @cttz_sel_const_true_false_extra_use(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 5, i32 -8
|
|
; CHECK-NEXT: call void @use(i32 [[S]])
|
|
; CHECK-NEXT: [[C:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[S]], i1 true)
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 -8
|
|
call void @use(i32 %s)
|
|
%c = call i32 @llvm.cttz.i32(i32 %s, i1 true)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @ctpop_sel_const_true_false(i1 %b) {
|
|
; CHECK-LABEL: @ctpop_sel_const_true_false(
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 30
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 -7
|
|
%c = call i32 @llvm.ctpop.i32(i32 %s)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @ctpop_sel_const_true(i1 %b, i32 %x) {
|
|
; CHECK-LABEL: @ctpop_sel_const_true(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 [[TMP1]]
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 %x
|
|
%c = call i32 @llvm.ctpop.i32(i32 %s)
|
|
ret i32 %c
|
|
}
|
|
|
|
define <3 x i7> @ctpop_sel_const_false(<3 x i1> %b, <3 x i7> %x) {
|
|
; CHECK-LABEL: @ctpop_sel_const_false(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call range(i7 0, 8) <3 x i7> @llvm.ctpop.v3i7(<3 x i7> [[X:%.*]])
|
|
; CHECK-NEXT: [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i7> [[TMP1]], <3 x i7> <i7 3, i7 7, i7 0>
|
|
; CHECK-NEXT: ret <3 x i7> [[C]]
|
|
;
|
|
%s = select <3 x i1> %b, <3 x i7> %x, <3 x i7> <i7 7, i7 -1, i7 0>
|
|
%c = call <3 x i7> @llvm.ctpop.v3i7(<3 x i7> %s)
|
|
ret <3 x i7> %c
|
|
}
|
|
|
|
define i32 @ctpop_sel_const_true_false_extra_use(i1 %b) {
|
|
; CHECK-LABEL: @ctpop_sel_const_true_false_extra_use(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 5, i32 7
|
|
; CHECK-NEXT: call void @use(i32 [[S]])
|
|
; CHECK-NEXT: [[C:%.*]] = call range(i32 2, 4) i32 @llvm.ctpop.i32(i32 [[S]])
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 7
|
|
call void @use(i32 %s)
|
|
%c = call i32 @llvm.ctpop.i32(i32 %s)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @usub_sat_rhs_const_select_all_const(i1 %b) {
|
|
; CHECK-LABEL: @usub_sat_rhs_const_select_all_const(
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 0, i32 3
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 10
|
|
%c = call i32 @llvm.usub.sat.i32(i32 %s, i32 7)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @usub_sat_rhs_var_select_all_const(i1 %b, i32 %x) {
|
|
; CHECK-LABEL: @usub_sat_rhs_var_select_all_const(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 5, i32 10
|
|
; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[S]], i32 [[X:%.*]])
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 10
|
|
%c = call i32 @llvm.usub.sat.i32(i32 %s, i32 %x)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @usub_sat_rhs_const_select_one_const(i1 %b, i32 %x) {
|
|
; CHECK-LABEL: @usub_sat_rhs_const_select_one_const(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X:%.*]], i32 7)
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 0, i32 [[TMP1]]
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 %x
|
|
%c = call i32 @llvm.usub.sat.i32(i32 %s, i32 7)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @usub_sat_rhs_const_select_no_const(i1 %b, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @usub_sat_rhs_const_select_no_const(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[Y:%.*]], i32 [[X:%.*]]
|
|
; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[S]], i32 7)
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 %y, i32 %x
|
|
%c = call i32 @llvm.usub.sat.i32(i32 %s, i32 7)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @usub_sat_lhs_const_select_all_const(i1 %b) {
|
|
; CHECK-LABEL: @usub_sat_lhs_const_select_all_const(
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 0
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, i32 5, i32 10
|
|
%c = call i32 @llvm.usub.sat.i32(i32 7, i32 %s)
|
|
ret i32 %c
|
|
}
|
|
|
|
@g1 = constant <2 x i32> zeroinitializer
|
|
@g2 = external global i8
|
|
declare <2 x i32> @llvm.masked.load.v2i32.p0(ptr, i32, <2 x i1>, <2 x i32>)
|
|
|
|
define <2 x i32> @non_speculatable(i1 %b) {
|
|
; CHECK-LABEL: @non_speculatable(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], ptr @g1, ptr @g2
|
|
; CHECK-NEXT: [[C:%.*]] = call <2 x i32> @llvm.masked.load.v2i32.p0(ptr nonnull align 64 [[S]], <2 x i1> <i1 true, i1 false>, <2 x i32> poison)
|
|
; CHECK-NEXT: ret <2 x i32> [[C]]
|
|
;
|
|
%s = select i1 %b, ptr @g1, ptr @g2
|
|
%c = call <2 x i32> @llvm.masked.load.v2i32.p0(ptr %s, i32 64, <2 x i1> <i1 true, i1 false>, <2 x i32> poison)
|
|
ret <2 x i32> %c
|
|
}
|
|
|
|
declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>)
|
|
|
|
define i32 @vec_to_scalar_select_scalar(i1 %b) {
|
|
; CHECK-LABEL: @vec_to_scalar_select_scalar(
|
|
; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 3, i32 7
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select i1 %b, <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>
|
|
%c = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %s)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i32 @vec_to_scalar_select_vector(<2 x i1> %b) {
|
|
; CHECK-LABEL: @vec_to_scalar_select_vector(
|
|
; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[B:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>
|
|
; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[S]])
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%s = select <2 x i1> %b, <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>
|
|
%c = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %s)
|
|
ret i32 %c
|
|
}
|
|
|
|
define i8 @test_drop_noundef(i1 %cond, i8 %val) {
|
|
; CHECK-LABEL: @test_drop_noundef(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.smin.i8(i8 [[VAL:%.*]], i8 0)
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 -1, i8 [[TMP0]]
|
|
; CHECK-NEXT: ret i8 [[RET]]
|
|
;
|
|
entry:
|
|
%sel = select i1 %cond, i8 -1, i8 %val
|
|
%ret = call noundef i8 @llvm.smin.i8(i8 %sel, i8 0)
|
|
ret i8 %ret
|
|
}
|
|
|
|
define i1 @pr85536(i32 %a) {
|
|
; CHECK-LABEL: @pr85536(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 31
|
|
; CHECK-NEXT: [[SHL1:%.*]] = shl nsw i32 -1, [[A]]
|
|
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL1]] to i64
|
|
; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[ZEXT]], 48
|
|
; CHECK-NEXT: [[SHR:%.*]] = ashr exact i64 [[SHL2]], 48
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smin.i64(i64 [[SHR]], i64 0)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65535
|
|
; CHECK-NEXT: [[RET1:%.*]] = icmp eq i64 [[TMP1]], 0
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i1 [[RET1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
entry:
|
|
%cmp1 = icmp ugt i32 %a, 30
|
|
%shl1 = shl nsw i32 -1, %a
|
|
%zext = zext i32 %shl1 to i64
|
|
%shl2 = shl i64 %zext, 48
|
|
%shr = ashr exact i64 %shl2, 48
|
|
%sel = select i1 %cmp1, i64 -1, i64 %shr
|
|
%smin = call noundef i64 @llvm.smin.i64(i64 %sel, i64 0)
|
|
%masked = and i64 %smin, 65535
|
|
%ret = icmp eq i64 %masked, 0
|
|
ret i1 %ret
|
|
}
|
|
|
|
define double @test_fabs_select1(double %a) {
|
|
; CHECK-LABEL: @test_fabs_select1(
|
|
; CHECK-NEXT: [[COND:%.*]] = fcmp uno double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], double +qnan, double [[A]]
|
|
; CHECK-NEXT: ret double [[SEL1]]
|
|
;
|
|
%cond = fcmp uno double %a, 0.000000e+00
|
|
%sel1 = select i1 %cond, double 0x7FF8000000000000, double %a
|
|
%fabs = call double @llvm.fabs.f64(double %sel1)
|
|
%sel2 = select i1 %cond, double %fabs, double %a
|
|
ret double %sel2
|
|
}
|
|
|
|
define <2 x double> @test_fabs_select1_vec(<2 x double> %a) {
|
|
; CHECK-LABEL: @test_fabs_select1_vec(
|
|
; CHECK-NEXT: [[COND:%.*]] = fcmp uno <2 x double> [[A:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[COND]], <2 x double> splat (double +qnan), <2 x double> [[A]]
|
|
; CHECK-NEXT: ret <2 x double> [[SEL2]]
|
|
;
|
|
%cond = fcmp uno <2 x double> %a, zeroinitializer
|
|
%sel1 = select <2 x i1> %cond, <2 x double> splat(double 0x7FF8000000000000), <2 x double> %a
|
|
%fabs = call <2 x double> @llvm.fabs.v2f64(<2 x double> %sel1)
|
|
%sel2 = select <2 x i1> %cond, <2 x double> %fabs, <2 x double> %a
|
|
ret <2 x double> %sel2
|
|
}
|
|
|
|
define double @test_fabs_select2(double %a) {
|
|
; CHECK-LABEL: @test_fabs_select2(
|
|
; CHECK-NEXT: [[ABS1:%.*]] = call double @llvm.fabs.f64(double [[A:%.*]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[ABS1]], +inf
|
|
; CHECK-NEXT: [[ABS2:%.*]] = select i1 [[CMP]], double 0.000000e+00, double [[ABS1]]
|
|
; CHECK-NEXT: ret double [[ABS2]]
|
|
;
|
|
%abs1 = call double @llvm.fabs.f64(double %a)
|
|
%cmp = fcmp oeq double %abs1, 0x7FF0000000000000
|
|
%sel = select i1 %cmp, double -0.000000e+00, double %abs1
|
|
%abs2 = call double @llvm.fabs.f64(double %sel)
|
|
ret double %abs2
|
|
}
|
|
|
|
; nsz flag should be dropped.
|
|
|
|
define double @test_fabs_select_fmf1(i1 %cond, double %a) {
|
|
; CHECK-LABEL: @test_fabs_select_fmf1(
|
|
; CHECK-NEXT: [[A:%.*]] = call double @llvm.fabs.f64(double [[A1:%.*]])
|
|
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[COND:%.*]], double 0.000000e+00, double [[A]]
|
|
; CHECK-NEXT: ret double [[FABS]]
|
|
;
|
|
%sel1 = select nnan ninf nsz i1 %cond, double 0.0, double %a
|
|
%fabs = call double @llvm.fabs.f64(double %sel1)
|
|
ret double %fabs
|
|
}
|
|
|
|
define double @test_fabs_select_fmf2(i1 %cond, double %a) {
|
|
; CHECK-LABEL: @test_fabs_select_fmf2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[A:%.*]])
|
|
; CHECK-NEXT: [[SEL1:%.*]] = select nnan ninf i1 [[COND:%.*]], double 0.000000e+00, double [[TMP1]]
|
|
; CHECK-NEXT: ret double [[SEL1]]
|
|
;
|
|
%sel1 = select i1 %cond, double 0.0, double %a
|
|
%fabs = call nnan ninf nsz double @llvm.fabs.f64(double %sel1)
|
|
ret double %fabs
|
|
}
|
|
|
|
define float @test_fabs_select_multiuse(i1 %cond, float %x) {
|
|
; CHECK-LABEL: @test_fabs_select_multiuse(
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], float [[X:%.*]], float +inf
|
|
; CHECK-NEXT: call void @usef32(float [[SELECT]])
|
|
; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
|
|
; CHECK-NEXT: ret float [[FABS]]
|
|
;
|
|
%select = select i1 %cond, float %x, float 0x7FF0000000000000
|
|
call void @usef32(float %select)
|
|
%fabs = call float @llvm.fabs.f32(float %select)
|
|
ret float %fabs
|
|
}
|
|
|
|
define float @test_fabs_select_multiuse_both_constant(i1 %cond, float %x) {
|
|
; CHECK-LABEL: @test_fabs_select_multiuse_both_constant(
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], float -1.000000e+00, float -2.000000e+00
|
|
; CHECK-NEXT: call void @usef32(float [[SELECT]])
|
|
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[COND]], float 1.000000e+00, float 2.000000e+00
|
|
; CHECK-NEXT: ret float [[FABS]]
|
|
;
|
|
%select = select i1 %cond, float -1.0, float -2.0
|
|
call void @usef32(float %select)
|
|
%fabs = call float @llvm.fabs.f32(float %select)
|
|
ret float %fabs
|
|
}
|
|
|
|
; Negative test: Don't replace with select between vector mask and zeroinitializer.
|
|
define <16 x i1> @test_select_of_active_lane_mask_bound(i64 %base, i64 %n, i1 %cond) {
|
|
; CHECK-LABEL: @test_select_of_active_lane_mask_bound(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i64 [[N:%.*]], i64 0
|
|
; CHECK-NEXT: [[MASK:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 [[BASE:%.*]], i64 [[S]])
|
|
; CHECK-NEXT: ret <16 x i1> [[MASK]]
|
|
;
|
|
%s = select i1 %cond, i64 %n, i64 0
|
|
%mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 %base, i64 %s)
|
|
ret <16 x i1> %mask
|
|
}
|
|
|
|
define <16 x i1> @test_select_of_active_lane_mask_bound_both_constant(i64 %base, i64 %n, i1 %cond) {
|
|
; CHECK-LABEL: @test_select_of_active_lane_mask_bound_both_constant(
|
|
; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], <16 x i1> splat (i1 true), <16 x i1> zeroinitializer
|
|
; CHECK-NEXT: ret <16 x i1> [[MASK]]
|
|
;
|
|
%s = select i1 %cond, i64 16, i64 0
|
|
%mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 0, i64 %s)
|
|
ret <16 x i1> %mask
|
|
}
|
|
|
|
define { i64, i1 } @test_select_of_overflow_intrinsic_operand(i64 %n, i1 %cond) {
|
|
; CHECK-LABEL: @test_select_of_overflow_intrinsic_operand(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[N:%.*]], i64 42)
|
|
; CHECK-NEXT: [[ADD_OVERFLOW:%.*]] = select i1 [[COND:%.*]], { i64, i1 } [[TMP1]], { i64, i1 } { i64 42, i1 false }
|
|
; CHECK-NEXT: ret { i64, i1 } [[ADD_OVERFLOW]]
|
|
;
|
|
%s = select i1 %cond, i64 %n, i64 0
|
|
%add_overflow = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s, i64 42)
|
|
ret { i64, i1 } %add_overflow
|
|
}
|
|
|
|
; Negative test: Can't fold struct-return into vector select.
|
|
define { <4 x float>, <4 x float> } @test_vector_cond_select_of_sincos_intrinsic_operand(<4 x float> %v, <4 x i1> %cond) {
|
|
; CHECK-LABEL: @test_vector_cond_select_of_sincos_intrinsic_operand(
|
|
; CHECK-NEXT: [[S:%.*]] = select <4 x i1> [[COND:%.*]], <4 x float> [[V:%.*]], <4 x float> zeroinitializer
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call { <4 x float>, <4 x float> } @llvm.sincos.v4f32(<4 x float> [[S]])
|
|
; CHECK-NEXT: ret { <4 x float>, <4 x float> } [[RESULT]]
|
|
;
|
|
%s = select <4 x i1> %cond, <4 x float> %v, <4 x float> zeroinitializer
|
|
%result = call { <4 x float>, <4 x float> } @llvm.sincos.v4f32(<4 x float> %s)
|
|
ret { <4 x float>, <4 x float> } %result
|
|
}
|
|
|
|
define { <4 x float>, <4 x float> } @test_select_of_sincos_intrinsic_operand(<4 x float> %v, i1 %cond) {
|
|
; CHECK-LABEL: @test_select_of_sincos_intrinsic_operand(
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call { <4 x float>, <4 x float> } @llvm.sincos.v4f32(<4 x float> [[S:%.*]])
|
|
; CHECK-NEXT: [[RESULT1:%.*]] = select i1 [[COND:%.*]], { <4 x float>, <4 x float> } [[RESULT]], { <4 x float>, <4 x float> } { <4 x float> zeroinitializer, <4 x float> splat (float 1.000000e+00) }
|
|
; CHECK-NEXT: ret { <4 x float>, <4 x float> } [[RESULT1]]
|
|
;
|
|
%s = select i1 %cond, <4 x float> %v, <4 x float> zeroinitializer
|
|
%result = call { <4 x float>, <4 x float> } @llvm.sincos.v4f32(<4 x float> %s)
|
|
ret { <4 x float>, <4 x float> } %result
|
|
}
|
|
|
|
define i8 @test_select_rotate_left(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_left(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], i8 2, i8 -1
|
|
; CHECK-NEXT: ret i8 [[RET]]
|
|
;
|
|
%s = select i1 %0, i8 1, i8 -1
|
|
%ret = call i8 @llvm.fshl.i8(i8 %s, i8 %s, i8 1)
|
|
ret i8 %ret
|
|
}
|
|
|
|
define i8 @test_select_rotate_left_multiuser(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_left_multiuser(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP0:%.*]], i8 1, i8 -1
|
|
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.fshl.i8(i8 [[S]], i8 [[S]], i8 1)
|
|
; CHECK-NEXT: call void @use(i8 [[S]])
|
|
; CHECK-NEXT: ret i8 [[RET]]
|
|
;
|
|
%s = select i1 %0, i8 1, i8 -1
|
|
%ret = call i8 @llvm.fshl.i8(i8 %s, i8 %s, i8 1)
|
|
call void @use(i8 %s)
|
|
ret i8 %ret
|
|
}
|
|
|
|
define <2 x i8> @test_select_rotate_left_splat(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_left_splat(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], <2 x i8> splat (i8 2), <2 x i8> splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i8> [[RET]]
|
|
;
|
|
%s = select i1 %0, <2 x i8> <i8 1, i8 1>, <2 x i8> <i8 -1, i8 -1>
|
|
%ret = call <2 x i8> @llvm.fshl.v2i8(<2 x i8> %s, <2 x i8> %s, <2 x i8> <i8 1, i8 1>)
|
|
ret <2 x i8> %ret
|
|
}
|
|
|
|
define <2 x i8> @test_select_rotate_left_splat_poison(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_left_splat_poison(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], <2 x i8> <i8 2, i8 poison>, <2 x i8> splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i8> [[RET]]
|
|
;
|
|
%s = select i1 %0, <2 x i8> <i8 1, i8 poison>, <2 x i8> <i8 -1, i8 -1>
|
|
%ret = call <2 x i8> @llvm.fshl.v2i8(<2 x i8> %s, <2 x i8> %s, <2 x i8> <i8 1, i8 1>)
|
|
ret <2 x i8> %ret
|
|
}
|
|
|
|
define <2 x i8> @test_select_rotate_left_non_splat(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_left_non_splat(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], <2 x i8> <i8 2, i8 4>, <2 x i8> <i8 -1, i8 -3>
|
|
; CHECK-NEXT: ret <2 x i8> [[RET]]
|
|
;
|
|
%s = select i1 %0, <2 x i8> <i8 1, i8 2>, <2 x i8> <i8 -1, i8 -2>
|
|
%ret = call <2 x i8> @llvm.fshl.v2i8(<2 x i8> %s, <2 x i8> %s, <2 x i8> <i8 1, i8 1>)
|
|
ret <2 x i8> %ret
|
|
}
|
|
|
|
define i8 @test_select_rotate_right(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_right(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], i8 2, i8 -1
|
|
; CHECK-NEXT: ret i8 [[RET]]
|
|
;
|
|
%s = select i1 %0, i8 1, i8 -1
|
|
%ret = call i8 @llvm.fshr.i8(i8 %s, i8 %s, i8 7)
|
|
ret i8 %ret
|
|
}
|
|
|
|
define i8 @test_select_rotate_right_multiuser(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_right_multiuser(
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP0:%.*]], i8 1, i8 -1
|
|
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.fshl.i8(i8 [[S]], i8 [[S]], i8 1)
|
|
; CHECK-NEXT: call void @use(i8 [[S]])
|
|
; CHECK-NEXT: ret i8 [[RET]]
|
|
;
|
|
%s = select i1 %0, i8 1, i8 -1
|
|
%ret = call i8 @llvm.fshr.i8(i8 %s, i8 %s, i8 7)
|
|
call void @use(i8 %s)
|
|
ret i8 %ret
|
|
}
|
|
|
|
define <2 x i8> @test_select_rotate_right_splat(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_right_splat(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], <2 x i8> splat (i8 2), <2 x i8> splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i8> [[RET]]
|
|
;
|
|
%s = select i1 %0, <2 x i8> <i8 1, i8 1>, <2 x i8> <i8 -1, i8 -1>
|
|
%ret = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %s, <2 x i8> %s, <2 x i8> <i8 7, i8 7>)
|
|
ret <2 x i8> %ret
|
|
}
|
|
|
|
define <2 x i8> @test_select_rotate_right_splat_poison(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_right_splat_poison(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], <2 x i8> <i8 2, i8 poison>, <2 x i8> splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i8> [[RET]]
|
|
;
|
|
%s = select i1 %0, <2 x i8> <i8 1, i8 poison>, <2 x i8> <i8 -1, i8 -1>
|
|
%ret = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %s, <2 x i8> %s, <2 x i8> <i8 7, i8 7>)
|
|
ret <2 x i8> %ret
|
|
}
|
|
|
|
define <2 x i8> @test_select_rotate_right_non_splat(i1 %0) {
|
|
; CHECK-LABEL: @test_select_rotate_right_non_splat(
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0:%.*]], <2 x i8> <i8 2, i8 4>, <2 x i8> <i8 -1, i8 -3>
|
|
; CHECK-NEXT: ret <2 x i8> [[RET]]
|
|
;
|
|
%s = select i1 %0, <2 x i8> <i8 1, i8 2>, <2 x i8> <i8 -1, i8 -2>
|
|
%ret = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %s, <2 x i8> %s, <2 x i8> <i8 7, i8 7>)
|
|
ret <2 x i8> %ret
|
|
}
|
|
|
|
define i32 @select_of_ctpop(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctpop(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[TMP1]])
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctpop1 = call i32 @llvm.ctpop.i32(i32 %x)
|
|
%ctpop2 = call i32 @llvm.ctpop.i32(i32 %y)
|
|
%sel = select i1 %cond, i32 %ctpop1, i32 %ctpop2
|
|
ret i32 %sel
|
|
}
|
|
|
|
; Negative test: TV is not ctpop, should not transform
|
|
define i32 @select_of_ctpop_negative_tv(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctpop_negative_tv(
|
|
; CHECK-NEXT: [[CTPOP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[CTPOP2]]
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctpop1 = add i32 %x, 0
|
|
%ctpop2 = call i32 @llvm.ctpop.i32(i32 %y)
|
|
%sel = select i1 %cond, i32 %ctpop1, i32 %ctpop2
|
|
ret i32 %sel
|
|
}
|
|
|
|
; Negative test: FV is not ctpop, should not transform
|
|
define i32 @select_of_ctpop_negative_fv(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctpop_negative_fv(
|
|
; CHECK-NEXT: [[CTPOP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CTPOP1]], i32 [[X:%.*]]
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctpop1 = call i32 @llvm.ctpop.i32(i32 %y)
|
|
%ctpop2 = add i32 %x, 0
|
|
%sel = select i1 %cond, i32 %ctpop1, i32 %ctpop2
|
|
ret i32 %sel
|
|
}
|
|
|
|
; Negative test: ctpop1 has multiple uses, don't transform
|
|
define i32 @select_of_ctpop_negative_multi_use(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctpop_negative_multi_use(
|
|
; CHECK-NEXT: [[CTPOP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
|
|
; CHECK-NEXT: call void @use(i32 [[CTPOP1]])
|
|
; CHECK-NEXT: [[CTPOP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CTPOP1]], i32 [[CTPOP2]]
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctpop1 = call i32 @llvm.ctpop.i32(i32 %x)
|
|
call void @use(i32 %ctpop1)
|
|
%ctpop2 = call i32 @llvm.ctpop.i32(i32 %y)
|
|
%sel = select i1 %cond, i32 %ctpop1, i32 %ctpop2
|
|
ret i32 %sel
|
|
}
|
|
|
|
define <4 x i32> @select_of_ctpop_vec(<4 x i1> %cond, <4 x i32> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: @select_of_ctpop_vec(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call range(i32 0, 33) <4 x i32> @llvm.ctpop.v4i32(<4 x i32> [[TMP1]])
|
|
; CHECK-NEXT: ret <4 x i32> [[SEL]]
|
|
;
|
|
%ctpop1 = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %x)
|
|
%ctpop2 = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %y)
|
|
%sel = select <4 x i1> %cond, <4 x i32> %ctpop1, <4 x i32> %ctpop2
|
|
ret <4 x i32> %sel
|
|
}
|
|
|
|
define i32 @select_of_ctlz(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctlz(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctlz1 = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
|
|
%ctlz2 = call i32 @llvm.ctlz.i32(i32 %y, i1 false)
|
|
%sel = select i1 %cond, i32 %ctlz1, i32 %ctlz2
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_of_ctlz_zero_poison_false(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctlz_zero_poison_false(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctlz1 = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
|
|
%ctlz2 = call i32 @llvm.ctlz.i32(i32 %y, i1 true)
|
|
%sel = select i1 %cond, i32 %ctlz1, i32 %ctlz2
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_of_ctlz_zero_poison_true(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctlz_zero_poison_true(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 true)
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctlz1 = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
|
|
%ctlz2 = call i32 @llvm.ctlz.i32(i32 %y, i1 true)
|
|
%sel = select i1 %cond, i32 %ctlz1, i32 %ctlz2
|
|
ret i32 %sel
|
|
}
|
|
|
|
; Negative test: ctlz1 has multiple uses, don't transform
|
|
define i32 @select_of_ctlz_negative_multi_use(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_ctlz_negative_multi_use(
|
|
; CHECK-NEXT: [[CTLZ1:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
|
|
; CHECK-NEXT: call void @use(i32 [[CTLZ1]])
|
|
; CHECK-NEXT: [[CTLZ2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[Y:%.*]], i1 false)
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CTLZ1]], i32 [[CTLZ2]]
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%ctlz1 = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
|
|
call void @use(i32 %ctlz1)
|
|
%ctlz2 = call i32 @llvm.ctlz.i32(i32 %y, i1 false)
|
|
%sel = select i1 %cond, i32 %ctlz1, i32 %ctlz2
|
|
ret i32 %sel
|
|
}
|
|
|
|
define <4 x i32> @select_of_ctlz_vec(<4 x i1> %cond, <4 x i32> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: @select_of_ctlz_vec(
|
|
; CHECK-NEXT: [[CTLZ2:%.*]] = call range(i32 0, 33) <4 x i32> @llvm.ctlz.v4i32(<4 x i32> [[Y:%.*]], i1 false)
|
|
; CHECK-NEXT: ret <4 x i32> [[CTLZ2]]
|
|
;
|
|
%ctlz1 = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %x, i1 false)
|
|
%ctlz2 = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %y, i1 false)
|
|
%sel = select <4 x i1> %cond, <4 x i32> %ctlz2, <4 x i32> %ctlz2
|
|
ret <4 x i32> %sel
|
|
}
|
|
|
|
define i32 @select_of_cttz(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_cttz(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP1]], i1 false)
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%cttz1 = call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
|
%cttz2 = call i32 @llvm.cttz.i32(i32 %y, i1 false)
|
|
%sel = select i1 %cond, i32 %cttz1, i32 %cttz2
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_of_abs(i1 %cond, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @select_of_abs(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
|
|
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 false)
|
|
; CHECK-NEXT: ret i32 [[SEL]]
|
|
;
|
|
%abs1 = call i32 @llvm.abs.i32(i32 %x, i1 false)
|
|
%abs2 = call i32 @llvm.abs.i32(i32 %y, i1 false)
|
|
%sel = select i1 %cond, i32 %abs1, i32 %abs2
|
|
ret i32 %sel
|
|
}
|