[clang-tools-extra] [clang] [compiler-rt] [flang] [llvm] intrinsic to generate a ubfx instruction (PR #80103)
https://github.com/RamaMalladiAWS updated https://github.com/llvm/llvm-project/pull/80103 >From e6df837fa223046677b162f817b2b00a99b68a74 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 26 Jan 2024 18:49:23 + Subject: [PATCH] intrinsic to generate a ubfx instruction --- llvm/include/llvm/IR/IntrinsicsAArch64.td | 3 ++ .../Target/AArch64/AArch64ISelDAGToDAG.cpp| 13 +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 6 .../test/CodeGen/AArch64/ubfx-64-intrinsic.ll | 36 +++ 4 files changed, 58 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 921e5b95ae03e..868265dcd1192 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -855,6 +855,9 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv [IntrNoMem]>; def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; +def int_aarch64_ubfx : DefaultAttrsIntrinsic< +[llvm_anyint_ty], [llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty], +[IntrNoMem, ImmArg>, ImmArg>]>; } //===--===// diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 163ed520a8a67..acdc9f70cb14c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -5230,6 +5230,19 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { switch (IntNo) { default: break; +case Intrinsic::aarch64_ubfx: { + SDLoc DL(Node); + auto lsb = cast(Node->getOperand(2))->getZExtValue(); + auto width = cast(Node->getOperand(3))->getZExtValue(); + auto ImmR = (VT.getSizeInBits() - lsb) % VT.getSizeInBits(); + auto ImmS = width - 1; + SDValue Ops[] = {Node->getOperand(1), + CurDAG->getTargetConstant(ImmR, DL, VT), + CurDAG->getTargetConstant(ImmS, DL, VT)}; + unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri; + CurDAG->SelectNodeTo(Node, Opc, VT, Ops); + return; +} case Intrinsic::aarch64_tagp: SelectTagP(Node); return; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 03baa7497615e..cc2d094cb0755 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2558,6 +2558,12 @@ def : Pat<(rotr GPR32:$Rn, (i64 imm0_31:$imm)), def : Pat<(rotr GPR64:$Rn, (i64 imm0_63:$imm)), (EXTRXrri GPR64:$Rn, GPR64:$Rn, imm0_63:$imm)>; +def SDT_AArch64UBFX_32bit : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; +def SDT_AArch64UBFX_64bit : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, i64>]>; + +def aarch64_ubfxw : SDNode<"AArch64::UBFMWri", SDT_AArch64UBFX_32bit>; +def aarch64_ubfxx : SDNode<"AArch64::UBFMXri", SDT_AArch64UBFX_64bit>; + //===--===// // Other bitfield immediate instructions. //===--===// diff --git a/llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll b/llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll new file mode 100644 index 0..a98cd99f3a16c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI + +define i32 @f32(i32 %A) nounwind { +; CHECK-LABEL: f32: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ubfiz w0, w0, #3, #3 +; CHECK-GI-NEXT: ret +entry: + %tmp = call i32 @llvm.aarch64.ubfx.i32(i32 %A, i32 3, i32 3) + ret i32 %tmp +} + +define i64 @f64(i64 %A) nounwind { +; CHECK-LABEL: f64: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ubfiz x0, x0, #38, #4 +; CHECK-GI-NEXT: ret +entry: + %tmp = call i64 @llvm.aarch64.ubfx.i64(i64 %A, i64 38, i64 4) + ret i64 %tmp +} + +define i64 @f64_1(i64 %A) nounwind { +; CHECK-LABEL: f64_1: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ubfx x0, x0, #50, #3 +; CHECK-GI-NEXT: ret +entry: + %tmp = call i64 @llvm.aarch64.ubfx.i64(i64 %A, i64 14, i64 53) + ret i64 %tmp +} + +declare i32 @llvm.aarch64.ubfx.i32(i32, i32, i32) +declare i64 @llvm.aarch64.ubfx.i64(i64, i64, i64) + ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [flang] [clang] [compiler-rt] [llvm][AArch64] intrinsic to generate a ubfx instruction (PR #80103)
https://github.com/RamaMalladiAWS updated https://github.com/llvm/llvm-project/pull/80103 >From e6df837fa223046677b162f817b2b00a99b68a74 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 26 Jan 2024 18:49:23 + Subject: [PATCH 1/2] intrinsic to generate a ubfx instruction --- llvm/include/llvm/IR/IntrinsicsAArch64.td | 3 ++ .../Target/AArch64/AArch64ISelDAGToDAG.cpp| 13 +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 6 .../test/CodeGen/AArch64/ubfx-64-intrinsic.ll | 36 +++ 4 files changed, 58 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 921e5b95ae03e..868265dcd1192 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -855,6 +855,9 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv [IntrNoMem]>; def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; +def int_aarch64_ubfx : DefaultAttrsIntrinsic< +[llvm_anyint_ty], [llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty], +[IntrNoMem, ImmArg>, ImmArg>]>; } //===--===// diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 163ed520a8a67..acdc9f70cb14c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -5230,6 +5230,19 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { switch (IntNo) { default: break; +case Intrinsic::aarch64_ubfx: { + SDLoc DL(Node); + auto lsb = cast(Node->getOperand(2))->getZExtValue(); + auto width = cast(Node->getOperand(3))->getZExtValue(); + auto ImmR = (VT.getSizeInBits() - lsb) % VT.getSizeInBits(); + auto ImmS = width - 1; + SDValue Ops[] = {Node->getOperand(1), + CurDAG->getTargetConstant(ImmR, DL, VT), + CurDAG->getTargetConstant(ImmS, DL, VT)}; + unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri; + CurDAG->SelectNodeTo(Node, Opc, VT, Ops); + return; +} case Intrinsic::aarch64_tagp: SelectTagP(Node); return; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 03baa7497615e..cc2d094cb0755 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2558,6 +2558,12 @@ def : Pat<(rotr GPR32:$Rn, (i64 imm0_31:$imm)), def : Pat<(rotr GPR64:$Rn, (i64 imm0_63:$imm)), (EXTRXrri GPR64:$Rn, GPR64:$Rn, imm0_63:$imm)>; +def SDT_AArch64UBFX_32bit : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; +def SDT_AArch64UBFX_64bit : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, i64>]>; + +def aarch64_ubfxw : SDNode<"AArch64::UBFMWri", SDT_AArch64UBFX_32bit>; +def aarch64_ubfxx : SDNode<"AArch64::UBFMXri", SDT_AArch64UBFX_64bit>; + //===--===// // Other bitfield immediate instructions. //===--===// diff --git a/llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll b/llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll new file mode 100644 index 0..a98cd99f3a16c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ubfx-64-intrinsic.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI + +define i32 @f32(i32 %A) nounwind { +; CHECK-LABEL: f32: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ubfiz w0, w0, #3, #3 +; CHECK-GI-NEXT: ret +entry: + %tmp = call i32 @llvm.aarch64.ubfx.i32(i32 %A, i32 3, i32 3) + ret i32 %tmp +} + +define i64 @f64(i64 %A) nounwind { +; CHECK-LABEL: f64: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ubfiz x0, x0, #38, #4 +; CHECK-GI-NEXT: ret +entry: + %tmp = call i64 @llvm.aarch64.ubfx.i64(i64 %A, i64 38, i64 4) + ret i64 %tmp +} + +define i64 @f64_1(i64 %A) nounwind { +; CHECK-LABEL: f64_1: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ubfx x0, x0, #50, #3 +; CHECK-GI-NEXT: ret +entry: + %tmp = call i64 @llvm.aarch64.ubfx.i64(i64 %A, i64 14, i64 53) + ret i64 %tmp +} + +declare i32 @llvm.aarch64.ubfx.i32(i32, i32, i32) +declare i64 @llvm.aarch64.ubfx.i64(i64, i64, i64) + >From affc65a205c95ed7f48daf80027c04b85debfe9a Mon Sep 17 00:00:00 2001 From: Rama Malladi Date: Wed, 31 Jan 2024 21:13:50 + Subject: [PATCH 2/2] moved aarch64_ubfx to a new Bit Field Instructions section --- llvm/include/llvm/IR/IntrinsicsAArch64.td | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/llvm/include/llv
[clang-tools-extra] [llvm] [flang] [clang] [compiler-rt] [llvm][AArch64] intrinsic to generate a ubfx instruction (PR #80103)
@@ -855,6 +855,9 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv [IntrNoMem]>; def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; +def int_aarch64_ubfx : DefaultAttrsIntrinsic< RamaMalladiAWS wrote: Addressed it in https://github.com/llvm/llvm-project/pull/80103/commits/affc65a205c95ed7f48daf80027c04b85debfe9a https://github.com/llvm/llvm-project/pull/80103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] [clang-tools-extra] [lldb] [llvm] [lld] [libc] [clang] intrinsic to generate a bfi instruction (PR #79655)
https://github.com/RamaMalladiAWS updated https://github.com/llvm/llvm-project/pull/79655 >From 96aba7076392fb7f7479ec3a313ced5cfb714f81 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 26 Jan 2024 18:56:32 + Subject: [PATCH 1/2] intrinsic to generate a bfi instruction --- llvm/include/llvm/IR/IntrinsicsAArch64.td | 3 +++ .../Target/AArch64/AArch64ISelDAGToDAG.cpp| 13 llvm/lib/Target/AArch64/AArch64InstrInfo.td | 8 llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll | 20 +++ 4 files changed, 44 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 921e5b95ae03e8..9eb5154c95138f 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -855,6 +855,9 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv [IntrNoMem]>; def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; +def int_aarch64_bfi : DefaultAttrsIntrinsic< +[llvm_anyint_ty], [llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty], +[IntrNoMem, ImmArg>, ImmArg>]>; } //===--===// diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 163ed520a8a677..1fe3f95d54d131 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -5230,6 +5230,19 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { switch (IntNo) { default: break; +case Intrinsic::aarch64_bfi: { + SDLoc DL(Node); + auto lsb = cast(Node->getOperand(3))->getZExtValue(); + auto width = cast(Node->getOperand(4))->getZExtValue(); + auto ImmR = (VT.getSizeInBits() - lsb) % VT.getSizeInBits(); + auto ImmS = width - 1; + SDValue Ops[] = {Node->getOperand(1), Node->getOperand(2), + CurDAG->getConstant(ImmR, DL, VT), + CurDAG->getConstant(ImmS, DL, VT)}; + unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri; + CurDAG->SelectNodeTo(Node, Opc, VT, Ops); + return; +} case Intrinsic::aarch64_tagp: SelectTagP(Node); return; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 03baa7497615e3..afa911abad7982 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2558,6 +2558,14 @@ def : Pat<(rotr GPR32:$Rn, (i64 imm0_31:$imm)), def : Pat<(rotr GPR64:$Rn, (i64 imm0_63:$imm)), (EXTRXrri GPR64:$Rn, GPR64:$Rn, imm0_63:$imm)>; +def SDT_AArch64BFI_32bit : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, +SDTCisVT<2, i32>]>; +def SDT_AArch64BFI_64bit : SDTypeProfile<1, 2, [SDTCisVT<0, i64>, SDTCisVT<1, i64>, +SDTCisVT<2, i64>]>; + +def aarch64_bfiw : SDNode<"AArch64::BFMWri", SDT_AArch64BFI_32bit>; +def aarch64_bfix : SDNode<"AArch64::BFMXri", SDT_AArch64BFI_64bit>; + //===--===// // Other bitfield immediate instructions. //===--===// diff --git a/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll b/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll new file mode 100644 index 00..99b23fb1101d6c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll @@ -0,0 +1,20 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s -o -| FileCheck %s + +define i32 @f32(i32 %A, i32 %B) nounwind { +; CHECK-NEXT:bfi r0, r1, #4, #2 +entry: + %tmp32 = call i32 @llvm.aarch64.bfi.i32(i32 %A, i32 %B, i32 4, i32 2) + ret i32 %tmp32 +} + +define i64 @f64(i64 %A, i64 %B) nounwind { +; CHECK-NEXT:bfi r0, r1, #23, #8 +entry: + %tmp64 = call i64 @llvm.aarch64.bfi.i64(i64 %A, i64 %B, i64 23, i64 8) + ret i64 %tmp64 +} + +declare i32 @llvm.aarch64.bfi.i32(i32, i32, i32, i32) +declare i64 @llvm.aarch64.bfi.i64(i64, i64, i64, i64) + >From d5e3ad3893b03fc6c5dc1d4648c004125ac0dd5c Mon Sep 17 00:00:00 2001 From: Rama Malladi <98832537+ramamalladi...@users.noreply.github.com> Date: Fri, 26 Jan 2024 18:09:25 -0600 Subject: [PATCH 2/2] Update bfi-64-intrinsic.ll --- llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll b/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll index 99b23fb1101d6c..11ecde6b6fab20 100644 --- a/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll +++ b/llvm/tes
[libc] [lld] [lldb] [libcxx] [llvm] [clang] [clang-tools-extra] intrinsic to generate a bfi instruction (PR #79655)
https://github.com/RamaMalladiAWS closed https://github.com/llvm/llvm-project/pull/79655 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] [clang-tools-extra] [llvm] [clang] [libc] [lld] [lldb] intrinsic to generate a bfi instruction (PR #79655)
RamaMalladiAWS wrote: Unable to get Windows build target machine allocated. Will reattempt another submission. https://github.com/llvm/llvm-project/pull/79655 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [mlir] [clang-tools-extra] [libcxx] [compiler-rt] [flang] [libc] [lldb] [clang] intrinsic to generate a bfi instruction (PR #79672)
https://github.com/RamaMalladiAWS updated https://github.com/llvm/llvm-project/pull/79672 >From 1928947cf7563aea26bffd7a8f3603ade1ca31d6 Mon Sep 17 00:00:00 2001 From: Rama Malladi Date: Sat, 27 Jan 2024 02:11:47 + Subject: [PATCH] intrinsic to generate a bfi instruction BFI: Bit Field Insert copies any number of low order bits from a register into the same number of adjacent bits at any position in the destination register. This PR generates the BFI instruction by implementing an intrinsic function that can be invoked from the LLVM-IR. --- llvm/include/llvm/IR/IntrinsicsAArch64.td | 3 +++ .../Target/AArch64/AArch64ISelDAGToDAG.cpp| 13 ++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 8 ++ llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll | 25 +++ 4 files changed, 49 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 921e5b95ae03e8d..9eb5154c95138f9 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -855,6 +855,9 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv [IntrNoMem]>; def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; +def int_aarch64_bfi : DefaultAttrsIntrinsic< +[llvm_anyint_ty], [llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty], +[IntrNoMem, ImmArg>, ImmArg>]>; } //===--===// diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 163ed520a8a677b..1fe3f95d54d1319 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -5230,6 +5230,19 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { switch (IntNo) { default: break; +case Intrinsic::aarch64_bfi: { + SDLoc DL(Node); + auto lsb = cast(Node->getOperand(3))->getZExtValue(); + auto width = cast(Node->getOperand(4))->getZExtValue(); + auto ImmR = (VT.getSizeInBits() - lsb) % VT.getSizeInBits(); + auto ImmS = width - 1; + SDValue Ops[] = {Node->getOperand(1), Node->getOperand(2), + CurDAG->getConstant(ImmR, DL, VT), + CurDAG->getConstant(ImmS, DL, VT)}; + unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri; + CurDAG->SelectNodeTo(Node, Opc, VT, Ops); + return; +} case Intrinsic::aarch64_tagp: SelectTagP(Node); return; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 03baa7497615e3d..afa911abad79824 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2558,6 +2558,14 @@ def : Pat<(rotr GPR32:$Rn, (i64 imm0_31:$imm)), def : Pat<(rotr GPR64:$Rn, (i64 imm0_63:$imm)), (EXTRXrri GPR64:$Rn, GPR64:$Rn, imm0_63:$imm)>; +def SDT_AArch64BFI_32bit : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, +SDTCisVT<2, i32>]>; +def SDT_AArch64BFI_64bit : SDTypeProfile<1, 2, [SDTCisVT<0, i64>, SDTCisVT<1, i64>, +SDTCisVT<2, i64>]>; + +def aarch64_bfiw : SDNode<"AArch64::BFMWri", SDT_AArch64BFI_32bit>; +def aarch64_bfix : SDNode<"AArch64::BFMXri", SDT_AArch64BFI_64bit>; + //===--===// // Other bitfield immediate instructions. //===--===// diff --git a/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll b/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll new file mode 100644 index 000..11ecde6b6fab20b --- /dev/null +++ b/llvm/test/CodeGen/AArch64/bfi-64-intrinsic.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI + +define i32 @f32(i32 %A, i32 %B) nounwind { +; CHECK-LABEL: f32: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: bfi w0, w1, #4, #2 +; CHECK-GI-NEXT: ret +entry: + %tmp32 = call i32 @llvm.aarch64.bfi.i32(i32 %A, i32 %B, i32 4, i32 2) + ret i32 %tmp32 +} + +define i64 @f64(i64 %A, i64 %B) nounwind { +; CHECK-LABEL: f64: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: bfi x0, x1, #23, #8 +; CHECK-GI-NEXT: ret +entry: + %tmp64 = call i64 @llvm.aarch64.bfi.i64(i64 %A, i64 %B, i64 23, i64 8) + ret i64 %tmp64 +} + +declare i32 @llvm.aarch64.bfi.i32(i32, i32, i32, i32) +declare i64 @llvm.aarch64.bfi.i64(i64, i64, i64, i64) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://list
[flang] [compiler-rt] [clang-tools-extra] [clang] [llvm] [libc] [lldb] [mlir] [libcxx] [AArch64] add intrinsic to generate a bfi instruction (PR #79672)
RamaMalladiAWS wrote: > Hello. Can you explain why this is needed, as opposed to using the equivalent > shift/and/ors? Hi @davemgreen, one of AWS customers requested for such an intrinsic to be made available so that they could consume it their IR directly. The reasoning they had was to use 1 instruction such `bfi` instead of a combination of `shift`, `and`, `or`. https://github.com/llvm/llvm-project/pull/79672 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libc] [lld] [llvm] [clang-tools-extra] [libcxx] [lldb] [clang] intrinsic to generate a bfi instruction (PR #79655)
RamaMalladiAWS wrote: Thank you @DavidSpickett https://github.com/llvm/llvm-project/pull/79655 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[compiler-rt] [llvm] [libc] [flang] [clang] [clang-tools-extra] [lldb] [libcxx] [mlir] [AArch64] add intrinsic to generate a bfi instruction (PR #79672)
RamaMalladiAWS wrote: > OK. We would not usually add intrinsics like this without a strong motivating > case, that could not be optimized in some other way. It is better to use > target independent options when available, and inline assembly is available > as a fallback if it is really needed. But I would recommend that they use > normal and/or/shift operations and let us know about places the compiler > isn't optimizing them as well as it could be. I completely agree with the approach @davemgreen. In this case, the IR sequence wasn't optimized to a `bfi`. I can try to get a test-case and create an issue for better sequence if feasible. Thanks again. https://github.com/llvm/llvm-project/pull/79672 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [flang] [llvm] [compiler-rt] [clang-tools-extra] [mlir] [libcxx] [clang] [libc] [AArch64] add intrinsic to generate a bfi instruction (PR #79672)
RamaMalladiAWS wrote: > @RamaMalladiAWS Do you have examples of the IR that fails to lower to BFI? > These things often turn out to be either a missing middle-end > canonicalization or maybe a case that could be added to existing pattern > matching in the back-end. Yes, @RKSimon, I will try to get some test-cases in the next couple of days and we can evaluate the issues if any. Thank you. https://github.com/llvm/llvm-project/pull/79672 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Driver][AArch64] Add support for aarch64-amazon-linux triple (PR #109263)
https://github.com/RamaMalladiAWS approved this pull request. Looks good @peterwaller-arm . https://github.com/llvm/llvm-project/pull/109263 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits