diff options
Diffstat (limited to 'test/Transforms/InstCombine/amdgcn-intrinsics.ll')
-rw-r--r-- | test/Transforms/InstCombine/amdgcn-intrinsics.ll | 903 |
1 files changed, 903 insertions, 0 deletions
diff --git a/test/Transforms/InstCombine/amdgcn-intrinsics.ll b/test/Transforms/InstCombine/amdgcn-intrinsics.ll index a228968f25bce..deae5502bcdb8 100644 --- a/test/Transforms/InstCombine/amdgcn-intrinsics.ll +++ b/test/Transforms/InstCombine/amdgcn-intrinsics.ll @@ -7,6 +7,12 @@ declare float @llvm.amdgcn.rcp.f32(float) nounwind readnone declare double @llvm.amdgcn.rcp.f64(double) nounwind readnone +; CHECK-LABEL: @test_constant_fold_rcp_f32_undef +; CHECK-NEXT: ret float undef +define float @test_constant_fold_rcp_f32_undef() nounwind { + %val = call float @llvm.amdgcn.rcp.f32(float undef) nounwind readnone + ret float %val +} ; CHECK-LABEL: @test_constant_fold_rcp_f32_1 ; CHECK-NEXT: ret float 1.000000e+00 @@ -50,6 +56,18 @@ define double @test_constant_fold_rcp_f64_43() nounwind { ret double %val } +; -------------------------------------------------------------------- +; llvm.amdgcn.rsq +; -------------------------------------------------------------------- + +declare float @llvm.amdgcn.rsq.f32(float) nounwind readnone + +; CHECK-LABEL: @test_constant_fold_rsq_f32_undef +; CHECK-NEXT: ret float undef +define float @test_constant_fold_rsq_f32_undef() nounwind { + %val = call float @llvm.amdgcn.rsq.f32(float undef) nounwind readnone + ret float %val +} ; -------------------------------------------------------------------- ; llvm.amdgcn.frexp.mant @@ -633,3 +651,888 @@ define float @cos_fabs_fneg_f32(float %x) { %cos = call float @llvm.amdgcn.cos.f32(float %x.fabs.fneg) ret float %cos } + +; -------------------------------------------------------------------- +; llvm.amdgcn.cvt.pkrtz +; -------------------------------------------------------------------- + +declare <2 x half> @llvm.amdgcn.cvt.pkrtz(float, float) nounwind readnone + +; CHECK-LABEL: @vars_lhs_cvt_pkrtz( +; CHECK: %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %x, float %y) +define <2 x half> @vars_lhs_cvt_pkrtz(float %x, float %y) { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %x, float %y) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @constant_lhs_cvt_pkrtz( +; CHECK: %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float 0.000000e+00, float %y) +define <2 x half> @constant_lhs_cvt_pkrtz(float %y) { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float 0.0, float %y) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @constant_rhs_cvt_pkrtz( +; CHECK: %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %x, float 0.000000e+00) +define <2 x half> @constant_rhs_cvt_pkrtz(float %x) { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %x, float 0.0) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @undef_lhs_cvt_pkrtz( +; CHECK: %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float undef, float %y) +define <2 x half> @undef_lhs_cvt_pkrtz(float %y) { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float undef, float %y) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @undef_rhs_cvt_pkrtz( +; CHECK: %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %x, float undef) +define <2 x half> @undef_rhs_cvt_pkrtz(float %x) { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %x, float undef) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @undef_cvt_pkrtz( +; CHECK: ret <2 x half> undef +define <2 x half> @undef_cvt_pkrtz() { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float undef, float undef) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @constant_splat0_cvt_pkrtz( +; CHECK: ret <2 x half> zeroinitializer +define <2 x half> @constant_splat0_cvt_pkrtz() { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float 0.0, float 0.0) + ret <2 x half> %cvt +} + +; CHECK-LABEL: @constant_cvt_pkrtz( +; CHECK: ret <2 x half> <half 0xH4000, half 0xH4400> +define <2 x half> @constant_cvt_pkrtz() { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float 2.0, float 4.0) + ret <2 x half> %cvt +} + +; Test constant values where rtz changes result +; CHECK-LABEL: @constant_rtz_pkrtz( +; CHECK: ret <2 x half> <half 0xH7BFF, half 0xH7BFF> +define <2 x half> @constant_rtz_pkrtz() { + %cvt = call <2 x half> @llvm.amdgcn.cvt.pkrtz(float 65535.0, float 65535.0) + ret <2 x half> %cvt +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.ubfe +; -------------------------------------------------------------------- + +declare i32 @llvm.amdgcn.ubfe.i32(i32, i32, i32) nounwind readnone +declare i64 @llvm.amdgcn.ubfe.i64(i64, i32, i32) nounwind readnone + +; CHECK-LABEL: @ubfe_var_i32( +; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 %width) +define i32 @ubfe_var_i32(i32 %src, i32 %offset, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_clear_high_bits_constant_offset_i32( +; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 5, i32 %width) +define i32 @ubfe_clear_high_bits_constant_offset_i32(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 133, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_clear_high_bits_constant_width_i32( +; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 5) +define i32 @ubfe_clear_high_bits_constant_width_i32(i32 %src, i32 %offset) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 133) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_width_0( +; CHECK-NEXT: ret i32 0 +define i32 @ubfe_width_0(i32 %src, i32 %offset) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 0) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_width_31( +; CHECK: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 31) +define i32 @ubfe_width_31(i32 %src, i32 %offset) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 31) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_width_32( +; CHECK-NEXT: ret i32 0 +define i32 @ubfe_width_32(i32 %src, i32 %offset) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 32) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_width_33( +; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 1) +define i32 @ubfe_width_33(i32 %src, i32 %offset) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 33) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_33( +; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 1, i32 %width) +define i32 @ubfe_offset_33(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 33, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_0( +; CHECK-NEXT: %1 = sub i32 32, %width +; CHECK-NEXT: %2 = shl i32 %src, %1 +; CHECK-NEXT: %bfe = lshr i32 %2, %1 +; CHECK-NEXT: ret i32 %bfe +define i32 @ubfe_offset_0(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 0, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_32( +; CHECK-NEXT: %1 = sub i32 32, %width +; CHECK-NEXT: %2 = shl i32 %src, %1 +; CHECK-NEXT: %bfe = lshr i32 %2, %1 +; CHECK-NEXT: ret i32 %bfe +define i32 @ubfe_offset_32(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 32, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_31( +; CHECK-NEXT: %1 = sub i32 32, %width +; CHECK-NEXT: %2 = shl i32 %src, %1 +; CHECK-NEXT: %bfe = lshr i32 %2, %1 +; CHECK-NEXT: ret i32 %bfe +define i32 @ubfe_offset_31(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 32, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_0_width_0( +; CHECK-NEXT: ret i32 0 +define i32 @ubfe_offset_0_width_0(i32 %src) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 0, i32 0) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_0_width_3( +; CHECK-NEXT: and i32 %src, 7 +; CHECK-NEXT: ret +define i32 @ubfe_offset_0_width_3(i32 %src) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 0, i32 3) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_3_width_1( +; CHECK-NEXT: %1 = lshr i32 %src, 3 +; CHECK-NEXT: and i32 %1, 1 +; CHECK-NEXT: ret i32 +define i32 @ubfe_offset_3_width_1(i32 %src) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 3, i32 1) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_3_width_4( +; CHECK-NEXT: %1 = lshr i32 %src, 3 +; CHECK-NEXT: and i32 %1, 15 +; CHECK-NEXT: ret i32 +define i32 @ubfe_offset_3_width_4(i32 %src) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 3, i32 4) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_0_0_0( +; CHECK-NEXT: ret i32 0 +define i32 @ubfe_0_0_0() { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 0, i32 0, i32 0) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_neg1_5_7( +; CHECK-NEXT: ret i32 127 +define i32 @ubfe_neg1_5_7() { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 -1, i32 5, i32 7) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_undef_src_i32( +; CHECK-NEXT: ret i32 undef +define i32 @ubfe_undef_src_i32(i32 %offset, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 undef, i32 %offset, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_undef_offset_i32( +; CHECK: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 undef, i32 %width) +define i32 @ubfe_undef_offset_i32(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 undef, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_undef_width_i32( +; CHECK: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 undef) +define i32 @ubfe_undef_width_i32(i32 %src, i32 %offset) { + %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 %offset, i32 undef) + ret i32 %bfe +} + +; CHECK-LABEL: @ubfe_offset_33_width_4_i64( +; CHECK-NEXT: %1 = lshr i64 %src, 33 +; CHECK-NEXT: %bfe = and i64 %1, 15 +define i64 @ubfe_offset_33_width_4_i64(i64 %src) { + %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 33, i32 4) + ret i64 %bfe +} + +; CHECK-LABEL: @ubfe_offset_0_i64( +; CHECK-NEXT: %1 = sub i32 64, %width +; CHECK-NEXT: %2 = zext i32 %1 to i64 +; CHECK-NEXT: %3 = shl i64 %src, %2 +; CHECK-NEXT: %bfe = lshr i64 %3, %2 +; CHECK-NEXT: ret i64 %bfe +define i64 @ubfe_offset_0_i64(i64 %src, i32 %width) { + %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 0, i32 %width) + ret i64 %bfe +} + +; CHECK-LABEL: @ubfe_offset_32_width_32_i64( +; CHECK-NEXT: %bfe = lshr i64 %src, 32 +; CHECK-NEXT: ret i64 %bfe +define i64 @ubfe_offset_32_width_32_i64(i64 %src) { + %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 32, i32 32) + ret i64 %bfe +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.sbfe +; -------------------------------------------------------------------- + +declare i32 @llvm.amdgcn.sbfe.i32(i32, i32, i32) nounwind readnone +declare i64 @llvm.amdgcn.sbfe.i64(i64, i32, i32) nounwind readnone + +; CHECK-LABEL: @sbfe_offset_31( +; CHECK-NEXT: %1 = sub i32 32, %width +; CHECK-NEXT: %2 = shl i32 %src, %1 +; CHECK-NEXT: %bfe = ashr i32 %2, %1 +; CHECK-NEXT: ret i32 %bfe +define i32 @sbfe_offset_31(i32 %src, i32 %width) { + %bfe = call i32 @llvm.amdgcn.sbfe.i32(i32 %src, i32 32, i32 %width) + ret i32 %bfe +} + +; CHECK-LABEL: @sbfe_neg1_5_7( +; CHECK-NEXT: ret i32 -1 +define i32 @sbfe_neg1_5_7() { + %bfe = call i32 @llvm.amdgcn.sbfe.i32(i32 -1, i32 5, i32 7) + ret i32 %bfe +} + +; CHECK-LABEL: @sbfe_offset_32_width_32_i64( +; CHECK-NEXT: %bfe = ashr i64 %src, 32 +; CHECK-NEXT: ret i64 %bfe +define i64 @sbfe_offset_32_width_32_i64(i64 %src) { + %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 32, i32 32) + ret i64 %bfe +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.exp +; -------------------------------------------------------------------- + +declare void @llvm.amdgcn.exp.f32(i32, i32, float, float, float, float, i1, i1) nounwind inaccessiblememonly + +; Make sure no crashing on invalid variable params +; CHECK-LABEL: @exp_invalid_inputs( +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 %en, float 1.000000e+00, float 2.000000e+00, float 5.000000e-01, float 4.000000e+00, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 %tgt, i32 15, float 1.000000e+00, float 2.000000e+00, float 5.000000e-01, float 4.000000e+00, i1 true, i1 false) +define void @exp_invalid_inputs(i32 %tgt, i32 %en) { + call void @llvm.amdgcn.exp.f32(i32 0, i32 %en, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 %tgt, i32 15, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + ret void +} + +; CHECK-LABEL: @exp_disabled_inputs_to_undef( +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 1, float 1.000000e+00, float undef, float undef, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 2, float undef, float 2.000000e+00, float undef, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 4, float undef, float undef, float 5.000000e-01, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 8, float undef, float undef, float undef, float 4.000000e+00, i1 true, i1 false) + +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 1, float %x, float undef, float undef, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 2, float undef, float %y, float undef, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 4, float undef, float undef, float %z, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 8, float undef, float undef, float undef, float %w, i1 true, i1 false) + +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 0, float undef, float undef, float undef, float undef, i1 true, i1 false) + +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 3, float 1.000000e+00, float 2.000000e+00, float undef, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 5, float 1.000000e+00, float undef, float 5.000000e-01, float undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 9, float 1.000000e+00, float undef, float undef, float 4.000000e+00, i1 false, i1 false) +; CHECK: call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float 1.000000e+00, float 2.000000e+00, float 5.000000e-01, float 4.000000e+00, i1 false, i1 false) +define void @exp_disabled_inputs_to_undef(float %x, float %y, float %z, float %w) { + ; enable src0..src3 constants + call void @llvm.amdgcn.exp.f32(i32 0, i32 1, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 2, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 4, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 8, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + + ; enable src0..src3 variables + call void @llvm.amdgcn.exp.f32(i32 0, i32 1, float %x, float %y, float %z, float %w, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 2, float %x, float %y, float %z, float %w, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 4, float %x, float %y, float %z, float %w, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 8, float %x, float %y, float %z, float %w, i1 true, i1 false) + + ; enable none + call void @llvm.amdgcn.exp.f32(i32 0, i32 0, float %x, float %y, float %z, float %w, i1 true, i1 false) + + ; enable different source combinations + call void @llvm.amdgcn.exp.f32(i32 0, i32 3, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 5, float 1.0, float 2.0, float 0.5, float 4.0, i1 true, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 9, float 1.0, float 2.0, float 0.5, float 4.0, i1 false, i1 false) + call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float 1.0, float 2.0, float 0.5, float 4.0, i1 false, i1 false) + + ret void +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.exp.compr +; -------------------------------------------------------------------- + +declare void @llvm.amdgcn.exp.compr.v2f16(i32, i32, <2 x half>, <2 x half>, i1, i1) nounwind inaccessiblememonly + +; CHECK-LABEL: @exp_compr_invalid_inputs( +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 %en, <2 x half> <half 0xH3C00, half 0xH4000>, <2 x half> <half 0xH3800, half 0xH4400>, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 %tgt, i32 5, <2 x half> <half 0xH3C00, half 0xH4000>, <2 x half> <half 0xH3800, half 0xH4400>, i1 true, i1 false) +define void @exp_compr_invalid_inputs(i32 %tgt, i32 %en) { + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 %en, <2 x half> <half 1.0, half 2.0>, <2 x half> <half 0.5, half 4.0>, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 %tgt, i32 5, <2 x half> <half 1.0, half 2.0>, <2 x half> <half 0.5, half 4.0>, i1 true, i1 false) + ret void +} + +; CHECK-LABEL: @exp_compr_disabled_inputs_to_undef( +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 0, <2 x half> undef, <2 x half> undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 1, <2 x half> <half 0xH3C00, half 0xH4000>, <2 x half> undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 2, <2 x half> <half 0xH3C00, half 0xH4000>, <2 x half> undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 3, <2 x half> <half 0xH3C00, half 0xH4000>, <2 x half> undef, i1 true, i1 false) + +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 0, <2 x half> undef, <2 x half> undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 1, <2 x half> %xy, <2 x half> undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 2, <2 x half> %xy, <2 x half> undef, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 3, <2 x half> %xy, <2 x half> undef, i1 true, i1 false) + +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 12, <2 x half> undef, <2 x half> %zw, i1 true, i1 false) +; CHECK: call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 15, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) +define void @exp_compr_disabled_inputs_to_undef(<2 x half> %xy, <2 x half> %zw) { + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 0, <2 x half> <half 1.0, half 2.0>, <2 x half> <half 0.5, half 4.0>, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 1, <2 x half> <half 1.0, half 2.0>, <2 x half> <half 0.5, half 4.0>, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 2, <2 x half> <half 1.0, half 2.0>, <2 x half> <half 0.5, half 4.0>, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 3, <2 x half> <half 1.0, half 2.0>, <2 x half> <half 0.5, half 4.0>, i1 true, i1 false) + + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 0, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 1, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 2, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 3, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) + + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 12, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) + call void @llvm.amdgcn.exp.compr.v2f16(i32 0, i32 15, <2 x half> %xy, <2 x half> %zw, i1 true, i1 false) + ret void +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.fmed3 +; -------------------------------------------------------------------- + +declare float @llvm.amdgcn.fmed3.f32(float, float, float) nounwind readnone + +; CHECK-LABEL: @fmed3_f32( +; CHECK: %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float %z) +define float @fmed3_f32(float %x, float %y, float %z) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float %z) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_canonicalize_x_c0_c1_f32( +; CHECK: call float @llvm.amdgcn.fmed3.f32(float %x, float 0.000000e+00, float 1.000000e+00) +define float @fmed3_canonicalize_x_c0_c1_f32(float %x) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0.0, float 1.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_canonicalize_c0_x_c1_f32( +; CHECK: call float @llvm.amdgcn.fmed3.f32(float %x, float 0.000000e+00, float 1.000000e+00) +define float @fmed3_canonicalize_c0_x_c1_f32(float %x) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %x, float 1.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_canonicalize_c0_c1_x_f32( +; CHECK: call float @llvm.amdgcn.fmed3.f32(float %x, float 0.000000e+00, float 1.000000e+00) +define float @fmed3_canonicalize_c0_c1_x_f32(float %x) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %x) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_canonicalize_x_y_c_f32( +; CHECK: call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 1.000000e+00) +define float @fmed3_canonicalize_x_y_c_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 1.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_canonicalize_x_c_y_f32( +; CHECK: %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 1.000000e+00) +define float @fmed3_canonicalize_x_c_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 1.0, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_canonicalize_c_x_y_f32( +; CHECK: call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 1.000000e+00) +define float @fmed3_canonicalize_c_x_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %x, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_undef_x_y_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_undef_x_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float undef, float %x, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_fmf_undef_x_y_f32( +; CHECK: call nnan float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_fmf_undef_x_y_f32(float %x, float %y) { + %med3 = call nnan float @llvm.amdgcn.fmed3.f32(float undef, float %x, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_x_undef_y_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_x_undef_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float undef, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_x_y_undef_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_x_y_undef_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float undef) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_qnan0_x_y_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_qnan0_x_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000000000000, float %x, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_x_qnan0_y_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_x_qnan0_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8000000000000, float %y) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_x_y_qnan0_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_x_y_qnan0_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF8000000000000) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_qnan1_x_y_f32( +; CHECK: call float @llvm.minnum.f32(float %x, float %y) +define float @fmed3_qnan1_x_y_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000100000000, float %x, float %y) + ret float %med3 +} + +; This can return any of the qnans. +; CHECK-LABEL: @fmed3_qnan0_qnan1_qnan2_f32( +; CHECK: ret float 0x7FF8002000000000 +define float @fmed3_qnan0_qnan1_qnan2_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000100000000, float 0x7FF8002000000000, float 0x7FF8030000000000) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_constant_src0_0_f32( +; CHECK: ret float 5.000000e-01 +define float @fmed3_constant_src0_0_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.5, float -1.0, float 4.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_constant_src0_1_f32( +; CHECK: ret float 5.000000e-01 +define float @fmed3_constant_src0_1_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.5, float 4.0, float -1.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_constant_src1_0_f32( +; CHECK: ret float 5.000000e-01 +define float @fmed3_constant_src1_0_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 0.5, float 4.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_constant_src1_1_f32( +; CHECK: ret float 5.000000e-01 +define float @fmed3_constant_src1_1_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 4.0, float 0.5, float -1.0) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_constant_src2_0_f32( +; CHECK: ret float 5.000000e-01 +define float @fmed3_constant_src2_0_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 4.0, float 0.5) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_constant_src2_1_f32( +; CHECK: ret float 5.000000e-01 +define float @fmed3_constant_src2_1_f32(float %x, float %y) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 4.0, float -1.0, float 0.5) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_x_qnan0_qnan1_f32( +; CHECK: ret float %x +define float @fmed3_x_qnan0_qnan1_f32(float %x) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8001000000000, float 0x7FF8002000000000) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_qnan0_x_qnan1_f32( +; CHECK: ret float %x +define float @fmed3_qnan0_x_qnan1_f32(float %x) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float %x, float 0x7FF8002000000000) + ret float %med3 +} + +; CHECK-LABEL: @fmed3_qnan0_qnan1_x_f32( +; CHECK: ret float %x +define float @fmed3_qnan0_qnan1_x_f32(float %x) { + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float 0x7FF8002000000000, float %x) + ret float %med3 +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.icmp +; -------------------------------------------------------------------- + +declare i64 @llvm.amdgcn.icmp.i32(i32, i32, i32) nounwind readnone convergent +declare i64 @llvm.amdgcn.icmp.i64(i64, i64, i32) nounwind readnone convergent + +; Make sure there's no crash for invalid input +; CHECK-LABEL: @invalid_nonconstant_icmp_code( +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 %c) +define i64 @invalid_nonconstant_icmp_code(i32 %a, i32 %b, i32 %c) { + %result = call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 %c) + ret i64 %result +} + +; CHECK-LABEL: @invalid_icmp_code( +; CHECK: %under = call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 31) +; CHECK: %over = call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 42) +define i64 @invalid_icmp_code(i32 %a, i32 %b) { + %under = call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 31) + %over = call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 42) + %or = or i64 %under, %over + ret i64 %or +} + +; CHECK-LABEL: @icmp_constant_inputs_false( +; CHECK: ret i64 0 +define i64 @icmp_constant_inputs_false() { + %result = call i64 @llvm.amdgcn.icmp.i32(i32 9, i32 8, i32 32) + ret i64 %result +} + +; CHECK-LABEL: @icmp_constant_inputs_true( +; CHECK: ret i64 -1 +define i64 @icmp_constant_inputs_true() { + %result = call i64 @llvm.amdgcn.icmp.i32(i32 9, i32 8, i32 34) + ret i64 %result +} + +; CHECK-LABEL: @icmp_constant_to_rhs_slt( +; CHECK: %result = call i64 @llvm.amdgcn.icmp.i32(i32 %x, i32 9, i32 38) +define i64 @icmp_constant_to_rhs_slt(i32 %x) { + %result = call i64 @llvm.amdgcn.icmp.i32(i32 9, i32 %x, i32 40) + ret i64 %result +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_icmp_eq_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 32) +define i64 @fold_icmp_ne_0_zext_icmp_eq_i32(i32 %a, i32 %b) { + %cmp = icmp eq i32 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_icmp_ne_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 33) +define i64 @fold_icmp_ne_0_zext_icmp_ne_i32(i32 %a, i32 %b) { + %cmp = icmp ne i32 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_icmp_sle_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 41) +define i64 @fold_icmp_ne_0_zext_icmp_sle_i32(i32 %a, i32 %b) { + %cmp = icmp sle i32 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_icmp_ugt_i64( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i64(i64 %a, i64 %b, i32 34) +define i64 @fold_icmp_ne_0_zext_icmp_ugt_i64(i64 %a, i64 %b) { + %cmp = icmp ugt i64 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_icmp_ult_swap_i64( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i64(i64 %a, i64 %b, i32 34) +define i64 @fold_icmp_ne_0_zext_icmp_ult_swap_i64(i64 %a, i64 %b) { + %cmp = icmp ugt i64 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 0, i32 %zext.cmp, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_fcmp_oeq_f32( +; CHECK-NEXT: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 1) +define i64 @fold_icmp_ne_0_zext_fcmp_oeq_f32(float %a, float %b) { + %cmp = fcmp oeq float %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_fcmp_une_f32( +; CHECK-NEXT: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 14) +define i64 @fold_icmp_ne_0_zext_fcmp_une_f32(float %a, float %b) { + %cmp = fcmp une float %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_ne_0_zext_fcmp_olt_f64( +; CHECK-NEXT: call i64 @llvm.amdgcn.fcmp.f64(double %a, double %b, i32 4) +define i64 @fold_icmp_ne_0_zext_fcmp_olt_f64(double %a, double %b) { + %cmp = fcmp olt double %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_sext_icmp_ne_0_i32( +; CHECK: %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 32) +define i64 @fold_icmp_sext_icmp_ne_0_i32(i32 %a, i32 %b) { + %cmp = icmp eq i32 %a, %b + %sext.cmp = sext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_eq_0_zext_icmp_eq_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 33) +define i64 @fold_icmp_eq_0_zext_icmp_eq_i32(i32 %a, i32 %b) { + %cmp = icmp eq i32 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_eq_0_zext_icmp_slt_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 39) +define i64 @fold_icmp_eq_0_zext_icmp_slt_i32(i32 %a, i32 %b) { + %cmp = icmp slt i32 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_eq_0_zext_fcmp_oeq_f32( +; CHECK-NEXT: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 14) +define i64 @fold_icmp_eq_0_zext_fcmp_oeq_f32(float %a, float %b) { + %cmp = fcmp oeq float %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_eq_0_zext_fcmp_ule_f32( +; CHECK-NEXT: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 2) +define i64 @fold_icmp_eq_0_zext_fcmp_ule_f32(float %a, float %b) { + %cmp = fcmp ule float %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_eq_0_zext_fcmp_ogt_f32( +; CHECK-NEXT: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 13) +define i64 @fold_icmp_eq_0_zext_fcmp_ogt_f32(float %a, float %b) { + %cmp = fcmp ogt float %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_zext_icmp_eq_1_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 32) +define i64 @fold_icmp_zext_icmp_eq_1_i32(i32 %a, i32 %b) { + %cmp = icmp eq i32 %a, %b + %zext.cmp = zext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_zext_argi1_eq_1_i32( +; CHECK: %zext.cond = zext i1 %cond to i32 +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cond, i32 0, i32 33) +define i64 @fold_icmp_zext_argi1_eq_1_i32(i1 %cond) { + %zext.cond = zext i1 %cond to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cond, i32 1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_zext_argi1_eq_neg1_i32( +; CHECK: %zext.cond = zext i1 %cond to i32 +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cond, i32 -1, i32 32) +define i64 @fold_icmp_zext_argi1_eq_neg1_i32(i1 %cond) { + %zext.cond = zext i1 %cond to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cond, i32 -1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_sext_argi1_eq_1_i32( +; CHECK: %sext.cond = sext i1 %cond to i32 +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cond, i32 1, i32 32) +define i64 @fold_icmp_sext_argi1_eq_1_i32(i1 %cond) { + %sext.cond = sext i1 %cond to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cond, i32 1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_sext_argi1_eq_neg1_i32( +; CHECK: %sext.cond = sext i1 %cond to i32 +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cond, i32 0, i32 33) +define i64 @fold_icmp_sext_argi1_eq_neg1_i32(i1 %cond) { + %sext.cond = sext i1 %cond to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cond, i32 -1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_sext_argi1_eq_neg1_i64( +; CHECK: %sext.cond = sext i1 %cond to i64 +; CHECK: call i64 @llvm.amdgcn.icmp.i64(i64 %sext.cond, i64 0, i32 33) +define i64 @fold_icmp_sext_argi1_eq_neg1_i64(i1 %cond) { + %sext.cond = sext i1 %cond to i64 + %mask = call i64 @llvm.amdgcn.icmp.i64(i64 %sext.cond, i64 -1, i32 32) + ret i64 %mask +} + +; TODO: Should be able to fold to false +; CHECK-LABEL: @fold_icmp_sext_icmp_eq_1_i32( +; CHECK: %cmp = icmp eq i32 %a, %b +; CHECK: %sext.cmp = sext i1 %cmp to i32 +; CHECK: %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cmp, i32 1, i32 32) +define i64 @fold_icmp_sext_icmp_eq_1_i32(i32 %a, i32 %b) { + %cmp = icmp eq i32 %a, %b + %sext.cmp = sext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cmp, i32 1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_sext_icmp_eq_neg1_i32( +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 32) +define i64 @fold_icmp_sext_icmp_eq_neg1_i32(i32 %a, i32 %b) { + %cmp = icmp eq i32 %a, %b + %sext.cmp = sext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cmp, i32 -1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_icmp_sext_icmp_sge_neg1_i32( +; CHECK: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 39) +define i64 @fold_icmp_sext_icmp_sge_neg1_i32(i32 %a, i32 %b) { + %cmp = icmp sge i32 %a, %b + %sext.cmp = sext i1 %cmp to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %sext.cmp, i32 -1, i32 32) + ret i64 %mask +} + +; CHECK-LABEL: @fold_not_icmp_ne_0_zext_icmp_sle_i32( +; CHECK-NEXT: call i64 @llvm.amdgcn.icmp.i32(i32 %a, i32 %b, i32 38) +define i64 @fold_not_icmp_ne_0_zext_icmp_sle_i32(i32 %a, i32 %b) { + %cmp = icmp sle i32 %a, %b + %not = xor i1 %cmp, true + %zext.cmp = zext i1 %not to i32 + %mask = call i64 @llvm.amdgcn.icmp.i32(i32 %zext.cmp, i32 0, i32 33) + ret i64 %mask +} + +; -------------------------------------------------------------------- +; llvm.amdgcn.fcmp +; -------------------------------------------------------------------- + +declare i64 @llvm.amdgcn.fcmp.f32(float, float, i32) nounwind readnone convergent + +; Make sure there's no crash for invalid input +; CHECK-LABEL: @invalid_nonconstant_fcmp_code( +; CHECK: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 %c) +define i64 @invalid_nonconstant_fcmp_code(float %a, float %b, i32 %c) { + %result = call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 %c) + ret i64 %result +} + +; CHECK-LABEL: @invalid_fcmp_code( +; CHECK: %under = call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 -1) +; CHECK: %over = call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 16) +define i64 @invalid_fcmp_code(float %a, float %b) { + %under = call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 -1) + %over = call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 16) + %or = or i64 %under, %over + ret i64 %or +} + +; CHECK-LABEL: @fcmp_constant_inputs_false( +; CHECK: ret i64 0 +define i64 @fcmp_constant_inputs_false() { + %result = call i64 @llvm.amdgcn.fcmp.f32(float 2.0, float 4.0, i32 1) + ret i64 %result +} + +; CHECK-LABEL: @fcmp_constant_inputs_true( +; CHECK: ret i64 -1 +define i64 @fcmp_constant_inputs_true() { + %result = call i64 @llvm.amdgcn.fcmp.f32(float 2.0, float 4.0, i32 4) + ret i64 %result +} + +; CHECK-LABEL: @fcmp_constant_to_rhs_olt( +; CHECK: %result = call i64 @llvm.amdgcn.fcmp.f32(float %x, float 4.000000e+00, i32 2) +define i64 @fcmp_constant_to_rhs_olt(float %x) { + %result = call i64 @llvm.amdgcn.fcmp.f32(float 4.0, float %x, i32 4) + ret i64 %result +} |