From 10c80524c6a82135914a98d70f276e0193b7e313 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 31 Jan 2018 23:54:16 +0000 Subject: [PATCH] DAG: Fix not truncating when promoting bswap/bitreverse These need to convert back to the original type, like any other promotion. llvm-svn: 323932 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 3 +- test/CodeGen/AMDGPU/bitreverse.ll | 13 ++- test/CodeGen/AMDGPU/bswap.ll | 125 +++++++++++++---------- 3 files changed, 84 insertions(+), 57 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 76aedfec2f8..e59c664fd8b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -4300,7 +4300,8 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) { ISD::SRL, dl, NVT, Tmp1, DAG.getConstant(DiffBits, dl, TLI.getShiftAmountTy(NVT, DAG.getDataLayout()))); - Results.push_back(Tmp1); + + Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1)); break; } case ISD::FP_TO_UINT: diff --git a/test/CodeGen/AMDGPU/bitreverse.ll b/test/CodeGen/AMDGPU/bitreverse.ll index f29bfb46b94..217a678709c 100644 --- a/test/CodeGen/AMDGPU/bitreverse.ll +++ b/test/CodeGen/AMDGPU/bitreverse.ll @@ -15,7 +15,7 @@ declare <2 x i64> @llvm.bitreverse.v2i64(<2 x i64>) #1 declare <4 x i64> @llvm.bitreverse.v4i64(<4 x i64>) #1 ; FUNC-LABEL: {{^}}s_brev_i16: -; SI: s_brev_b32 +; SI: s_brev_b32 define amdgpu_kernel void @s_brev_i16(i16 addrspace(1)* noalias %out, i16 %val) #0 { %brev = call i16 @llvm.bitreverse.i16(i16 %val) #1 store i16 %brev, i16 addrspace(1)* %out @@ -113,5 +113,16 @@ define amdgpu_kernel void @v_brev_v2i64(<2 x i64> addrspace(1)* noalias %out, <2 ret void } +; FUNC-LABEL: {{^}}missing_truncate_promote_bitreverse: +; VI: v_bfrev_b32_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 +define float @missing_truncate_promote_bitreverse(i32 %arg) { +bb: + %tmp = trunc i32 %arg to i16 + %tmp1 = call i16 @llvm.bitreverse.i16(i16 %tmp) + %tmp2 = bitcast i16 %tmp1 to half + %tmp3 = fpext half %tmp2 to float + ret float %tmp3 +} + attributes #0 = { nounwind } attributes #1 = { nounwind readnone } diff --git a/test/CodeGen/AMDGPU/bswap.ll b/test/CodeGen/AMDGPU/bswap.ll index eb3fc2fab34..33dbeef4348 100644 --- a/test/CodeGen/AMDGPU/bswap.ll +++ b/test/CodeGen/AMDGPU/bswap.ll @@ -1,6 +1,7 @@ -; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s -; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s +; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,SI,FUNC %s +; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,VI,FUNC %s +declare i16 @llvm.bswap.i16(i16) nounwind readnone declare i32 @llvm.bswap.i32(i32) nounwind readnone declare <2 x i32> @llvm.bswap.v2i32(<2 x i32>) nounwind readnone declare <4 x i32> @llvm.bswap.v4i32(<4 x i32>) nounwind readnone @@ -10,13 +11,13 @@ declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>) nounwind readnone declare <4 x i64> @llvm.bswap.v4i64(<4 x i64>) nounwind readnone ; FUNC-LABEL: @test_bswap_i32 -; SI: s_load_dword [[VAL:s[0-9]+]] -; SI-DAG: v_alignbit_b32 [[TMP0:v[0-9]+]], [[VAL]], [[VAL]], 8 -; SI-DAG: v_alignbit_b32 [[TMP1:v[0-9]+]], [[VAL]], [[VAL]], 24 -; SI-DAG: s_mov_b32 [[K:s[0-9]+]], 0xff00ff -; SI: v_bfi_b32 [[RESULT:v[0-9]+]], [[K]], [[TMP1]], [[TMP0]] -; SI: buffer_store_dword [[RESULT]] -; SI: s_endpgm +; GCN: s_load_dword [[VAL:s[0-9]+]] +; GCN-DAG: v_alignbit_b32 [[TMP0:v[0-9]+]], [[VAL]], [[VAL]], 8 +; GCN-DAG: v_alignbit_b32 [[TMP1:v[0-9]+]], [[VAL]], [[VAL]], 24 +; GCN-DAG: s_mov_b32 [[K:s[0-9]+]], 0xff00ff +; GCN: v_bfi_b32 [[RESULT:v[0-9]+]], [[K]], [[TMP1]], [[TMP0]] +; GCN: buffer_store_dword [[RESULT]] +; GCN: s_endpgm define amdgpu_kernel void @test_bswap_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) nounwind { %val = load i32, i32 addrspace(1)* %in, align 4 %bswap = call i32 @llvm.bswap.i32(i32 %val) nounwind readnone @@ -25,13 +26,13 @@ define amdgpu_kernel void @test_bswap_i32(i32 addrspace(1)* %out, i32 addrspace( } ; FUNC-LABEL: @test_bswap_v2i32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI: s_endpgm +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN: s_endpgm define amdgpu_kernel void @test_bswap_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %in) nounwind { %val = load <2 x i32>, <2 x i32> addrspace(1)* %in, align 8 %bswap = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %val) nounwind readnone @@ -40,19 +41,19 @@ define amdgpu_kernel void @test_bswap_v2i32(<2 x i32> addrspace(1)* %out, <2 x i } ; FUNC-LABEL: @test_bswap_v4i32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI: s_endpgm +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN: s_endpgm define amdgpu_kernel void @test_bswap_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) nounwind { %val = load <4 x i32>, <4 x i32> addrspace(1)* %in, align 16 %bswap = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %val) nounwind readnone @@ -61,31 +62,31 @@ define amdgpu_kernel void @test_bswap_v4i32(<4 x i32> addrspace(1)* %out, <4 x i } ; FUNC-LABEL: @test_bswap_v8i32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_alignbit_b32 -; SI-DAG: v_bfi_b32 -; SI: s_endpgm +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_alignbit_b32 +; GCN-DAG: v_bfi_b32 +; GCN: s_endpgm define amdgpu_kernel void @test_bswap_v8i32(<8 x i32> addrspace(1)* %out, <8 x i32> addrspace(1)* %in) nounwind { %val = load <8 x i32>, <8 x i32> addrspace(1)* %in, align 32 %bswap = call <8 x i32> @llvm.bswap.v8i32(<8 x i32> %val) nounwind readnone @@ -94,7 +95,7 @@ define amdgpu_kernel void @test_bswap_v8i32(<8 x i32> addrspace(1)* %out, <8 x i } ; FUNC-LABEL: {{^}}test_bswap_i64: -; SI-NOT: v_or_b32_e64 v{{[0-9]+}}, 0, 0 +; GCN-NOT: v_or_b32_e64 v{{[0-9]+}}, 0, 0 define amdgpu_kernel void @test_bswap_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %in) nounwind { %val = load i64, i64 addrspace(1)* %in, align 8 %bswap = call i64 @llvm.bswap.i64(i64 %val) nounwind readnone @@ -115,3 +116,17 @@ define amdgpu_kernel void @test_bswap_v4i64(<4 x i64> addrspace(1)* %out, <4 x i store <4 x i64> %bswap, <4 x i64> addrspace(1)* %out, align 32 ret void } + +; GCN-LABEL: {{^}}missing_truncate_promote_bswap: +; VI: v_and_b32 +; VI: v_alignbit_b32 +; VI: v_alignbit_b32 +; VI: v_bfi_b32 +define float @missing_truncate_promote_bswap(i32 %arg) { +bb: + %tmp = trunc i32 %arg to i16 + %tmp1 = call i16 @llvm.bswap.i16(i16 %tmp) + %tmp2 = bitcast i16 %tmp1 to half + %tmp3 = fpext half %tmp2 to float + ret float %tmp3 +}