From fed71f42bcaee10df40cb6f6645db40823da6ef4 Mon Sep 17 00:00:00 2001 From: PosteruOle Date: Tue, 14 Nov 2023 13:54:21 +0100 Subject: [PATCH 1/3] Added a simple test for modification on LegalizeDAG! --- llvm/lib/Target/X86/X86ISelLowering.cpp | 3 +-- llvm/test/CodeGen/X86/final_llc_test.ll | 10 ++++++++++ llvm/test/CodeGen/X86/final_llc_test.s | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/final_llc_test.ll create mode 100644 llvm/test/CodeGen/X86/final_llc_test.s diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 4dbf3c9771fefd8..02c262d73663a9d 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -30162,11 +30162,10 @@ static SDValue lowerAddSub(SDValue Op, SelectionDAG &DAG, return return_new; } - + if (VT == MVT::i16 || VT == MVT::i32) return lowerAddSubToHorizontalOp(Op, DAG, Subtarget); - if (VT == MVT::v32i16 || VT == MVT::v64i8) return splitVectorIntBinary(Op, DAG); diff --git a/llvm/test/CodeGen/X86/final_llc_test.ll b/llvm/test/CodeGen/X86/final_llc_test.ll new file mode 100644 index 000000000000000..1b79a0c9a827bb2 --- /dev/null +++ b/llvm/test/CodeGen/X86/final_llc_test.ll @@ -0,0 +1,10 @@ +; RUN: llc -debug %s 2>&1 | FileCheck %s + +; CHECK: Successfully custom legalized node +; CHECK-NEXT: ... replacing: t3: i32 = add t2, t2 +; CHECK-NEXT: with: t9: i32 = mul t2, Constant:i32<2> + +define i32 @test(i32 %0) { + %res = add i32 %0, %0 + ret i32 %res +} diff --git a/llvm/test/CodeGen/X86/final_llc_test.s b/llvm/test/CodeGen/X86/final_llc_test.s new file mode 100644 index 000000000000000..8b0f72e70c18101 --- /dev/null +++ b/llvm/test/CodeGen/X86/final_llc_test.s @@ -0,0 +1,16 @@ + .text + .file "final_llc_test.ll" + .globl test # -- Begin function test + .p2align 4, 0x90 + .type test,@function +test: # @test + .cfi_startproc +# %bb.0: + # kill: def $edi killed $edi def $rdi + leal (%rdi,%rdi), %eax + retq +.Lfunc_end0: + .size test, .Lfunc_end0-test + .cfi_endproc + # -- End function + .section ".note.GNU-stack","",@progbits From 605ed7e47281b2d963c3549c5ba128cb007afc3a Mon Sep 17 00:00:00 2001 From: PosteruOle Date: Mon, 20 Nov 2023 16:43:58 +0100 Subject: [PATCH 2/3] Added solutions and tests for the second LLVM phase's tasks! --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 31 ++++++++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 4 +- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 72 ++++++++++++++++++- llvm/test/CodeGen/X86/dagcombiner_test.ll | 18 +++++ llvm/test/CodeGen/X86/dagcombiner_test.s | 18 +++++ 5 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/X86/dagcombiner_test.ll create mode 100644 llvm/test/CodeGen/X86/dagcombiner_test.s diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f33bc94691bd07b..1629a7f118e279f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -14,6 +14,7 @@ // in the LLVM IR and exposed by the various codegen lowering phases. // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" @@ -2909,6 +2910,36 @@ SDValue DAGCombiner::visitADD(SDNode *N) { EVT VT = N0.getValueType(); SDLoc DL(N); + errs() << "Welcome to visitADD function!\n"; + + if(N0.getNode()->getOpcode()==ISD::ADD && N1.getNode()->getOpcode()==ISD::MUL){ + errs() << "We are on the right track!\n"; + SDNode *res1=N0.getNode(); + SDNode *square2=N1.getNode(); + if(res1->getOperand(0).getNode()->getOperand(0)==res1->getOperand(0).getNode()->getOperand(1) && res1->getOperand(0).getNode()->getOpcode()==ISD::MUL){ + errs() << "We have found the first square!\n"; + if(square2->getOperand(0)==square2->getOperand(1) && square2->getOpcode()==ISD::MUL){ + errs() << "We have found the second square!\n"; + SDNode *mul2=res1->getOperand(1).getNode(); + if(mul2->getOpcode()==ISD::MUL){ + SDNode *mul=mul2->getOperand(0).getNode(); + if(mul->getOperand(0)==res1->getOperand(0).getNode()->getOperand(0) && mul->getOperand(1)==square2->getOperand(0)){ + + errs() << "We have successfully recognized binomial square!\n"; + SDValue binom_tmp=DAG.getNode(ISD::ADD, DL, VT, mul->getOperand(0), mul->getOperand(1)); + SDValue binom=DAG.getNode(ISD::MUL, DL, VT, binom_tmp, binom_tmp); + errs() << "We have successfully created nodes that will decrease binomial square implementation!\n"; + + return binom; + } else { + errs() << "We haven't found a extended binomial square implementation!\n"; + } + } + } + } + } + + if (SDValue Combined = visitADDLike(N)) return Combined; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c7adfcc918a2f5f..aa75d38f53e169e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -983,6 +983,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) { // Figure out the correct action; the way to query this varies by opcode TargetLowering::LegalizeAction Action = TargetLowering::Legal; + // You should leave next line under the comment! //TargetLowering::LegalizeAction Action = TargetLowering::Custom; bool SimpleFinishLegalizing = true; switch (Node->getOpcode()) { @@ -1041,7 +1042,8 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) { Node->getOperand(2).getValueType()); break; case ISD::ADD: - Action=TargetLowering::Custom; + //If you want custom legalization for ISD::ADD instruction you can uncomment the followingf command! + //Action=TargetLowering::Custom; break; case ISD::SELECT_CC: case ISD::STRICT_FSETCC: diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index d33b4b3a9d9f738..cb7e2b82a6c0e14 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -4779,6 +4779,7 @@ bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *N) { } void X86DAGToDAGISel::Select(SDNode *Node) { + errs() << "We have entered the X86DAGToDAGISel::Select function!\n"; MVT NVT = Node->getSimpleValueType(0); unsigned Opcode = Node->getOpcode();; SDLoc dl(Node); @@ -4789,7 +4790,14 @@ void X86DAGToDAGISel::Select(SDNode *Node) { return; // Already selected. } - + errs() << "ISD::ADD = " << ISD::ADD << "\n"; + errs() << "ISD::SHL = " << ISD::SHL << "\n"; + errs() << "ISD::MUL = " << ISD::MUL << "\n"; + errs() << "MVT::i16 = " << MVT::i16 << "\n"; + errs() << "MVT::i32 = " << MVT::i32 << "\n"; + errs() << "MVT::i64 = " << MVT::i64 << "\n"; + errs() << "MVT NVT = " << NVT << "\n"; + errs() << "Opcode = " << Opcode << "\n"; switch (Opcode) { default: break; case ISD::INTRINSIC_W_CHAIN: { @@ -5064,8 +5072,7 @@ void X86DAGToDAGISel::Select(SDNode *Node) { // the patterns on the add/sub/and/or/xor with immediate paterns in the // tablegen files to check immediate use count without making the patterns // unavailable to the fast-isel table. - if (!CurDAG->shouldOptForSize()) - break; + errs() << "Here we should write solution for 3rd task!\n"; // Only handle i8/i16/i32/i64. if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64) @@ -5074,6 +5081,65 @@ void X86DAGToDAGISel::Select(SDNode *Node) { SDValue N0 = Node->getOperand(0); SDValue N1 = Node->getOperand(1); + if(Opcode==ISD::ADD && N0==N1 && NVT==MVT::i64){ + errs() << "We have entered if clause related to i64 type!\n"; + + SDVTList VT = CurDAG->getVTList(NVT); + SDValue Const2=CurDAG->getTargetConstant(2, dl, N0.getValueType()); + SDValue Ops[] = {N0, Const2}; + SDValue newNode=CurDAG->getNode(ISD::MUL, dl, VT, Ops); + ReplaceUses(Node, newNode.getNode()); + CurDAG->RemoveDeadNode(Node); + CurDAG->SelectNodeTo(newNode.getNode(), X86::IMUL64rri32, MVT::i64, Ops); + + return; + } + + if(Opcode==ISD::ADD && N0==N1 && NVT==MVT::i32){ + errs() << "We have entered if clause related to i32 type!\n"; + + SDVTList VT = CurDAG->getVTList(NVT); + SDValue Const2=CurDAG->getTargetConstant(2, dl, N0.getValueType()); + SDValue Ops[] = {N0, Const2}; + SDValue newNode=CurDAG->getNode(ISD::MUL, dl, VT, Ops); + ReplaceUses(Node, newNode.getNode()); + CurDAG->RemoveDeadNode(Node); + CurDAG->SelectNodeTo(newNode.getNode(), X86::IMUL32rri, MVT::i32, Ops); + + return; + } + + if(Opcode==ISD::ADD && N0==N1 && NVT==MVT::i16){ + errs() << "We have entered if clause related to i16 type!\n"; + + SDVTList VT = CurDAG->getVTList(NVT); + SDValue Const2=CurDAG->getTargetConstant(2, dl, N0.getValueType()); + SDValue Ops[] = {N0, Const2}; + SDValue newNode=CurDAG->getNode(ISD::MUL, dl, VT, Ops); + ReplaceUses(Node, newNode.getNode()); + CurDAG->RemoveDeadNode(Node); + CurDAG->SelectNodeTo(newNode.getNode(), X86::IMUL16rri, MVT::i16, Ops); + + return; + } + + if(Opcode==ISD::ADD && N0==N1 && NVT==MVT::i8){ + errs() << "We have entered if clause related to i8 type!\n"; + + SDVTList VT = CurDAG->getVTList(NVT); + SDValue Const2=CurDAG->getTargetConstant(2, dl, N0.getValueType()); + SDValue Ops[] = {N0, Const2}; + SDValue newNode=CurDAG->getNode(ISD::MUL, dl, VT, Ops); + ReplaceUses(Node, newNode.getNode()); + CurDAG->RemoveDeadNode(Node); + CurDAG->SelectNodeTo(newNode.getNode(), X86::IMUL16rri8, MVT::i8, Ops); + + return; + } + + if (!CurDAG->shouldOptForSize()) + break; + auto *Cst = dyn_cast(N1); if (!Cst) break; diff --git a/llvm/test/CodeGen/X86/dagcombiner_test.ll b/llvm/test/CodeGen/X86/dagcombiner_test.ll new file mode 100644 index 000000000000000..6a3af7368be4bf2 --- /dev/null +++ b/llvm/test/CodeGen/X86/dagcombiner_test.ll @@ -0,0 +1,18 @@ +; RUN: llc -debug %s 2>&1 | FileCheck %s + +; CHECK: We are on the right track! +; CHECK-NEXT: We have found the first square! +; CHECK-NEXT: We have found the second square! +; CHECK-NEXT: We have successfully recognized binomial square! +; CHECK: We have successfully created nodes that will decrease binomial square implementation! + +define i32 @test(i32 %0, i32 %1) { + %square1 = mul i32 %0, %0 + %square2 = mul i32 %1, %1 + %mul = mul i32 %0, %1 + %mul2 = mul i32 %mul, 2 + %res1 = add i32 %square1, %mul2 + %res2 = add i32 %res1, %square2 + ret i32 %res2 +} + diff --git a/llvm/test/CodeGen/X86/dagcombiner_test.s b/llvm/test/CodeGen/X86/dagcombiner_test.s new file mode 100644 index 000000000000000..8ac7c6ba713466b --- /dev/null +++ b/llvm/test/CodeGen/X86/dagcombiner_test.s @@ -0,0 +1,18 @@ + .text + .file "dagcombiner_test.ll" + .globl test # -- Begin function test + .p2align 4, 0x90 + .type test,@function +test: # @test + .cfi_startproc +# %bb.0: + # kill: def $esi killed $esi def $rsi + # kill: def $edi killed $edi def $rdi + leal (%rdi,%rsi), %eax + imull %eax, %eax + retq +.Lfunc_end0: + .size test, .Lfunc_end0-test + .cfi_endproc + # -- End function + .section ".note.GNU-stack","",@progbits From b57167a2ce9a11d0be4cc9ac611ba8b134bc2d08 Mon Sep 17 00:00:00 2001 From: PosteruOle Date: Mon, 20 Nov 2023 16:50:25 +0100 Subject: [PATCH 3/3] Added solutions and tests for the second LLVM phase's tasks! --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1629a7f118e279f..d3938ee85dd2b07 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2939,7 +2939,6 @@ SDValue DAGCombiner::visitADD(SDNode *N) { } } - if (SDValue Combined = visitADDLike(N)) return Combined;