Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Mortina Anastasiya Lab3 Var1 #235

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions llvm/lib/Target/X86/lab3/mortina_nastya/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(PluginName X86MortinaMulAddPass)

file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp)
add_llvm_pass_plugin(${PluginName}
${ALL_SOURCE_FILES}
DEPENDS
intrinsics_gen
X86
BUILDTREE_ONLY)

target_include_directories(${PluginName} PUBLIC ${PATH_TO_X86})

set(LLVM_TEST_DEPENDS ${PluginName} ${LLVM_TEST_DEPENDS} PARENT_SCOPE)
102 changes: 102 additions & 0 deletions llvm/lib/Target/X86/lab3/mortina_nastya/X86MortinaMulAdd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "X86.h"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
class MortinaMulAddPass : public MachineFunctionPass {
public:
static char ID;
MortinaMulAddPass() : MachineFunctionPass(ID) {}

bool runOnMachineFunction(MachineFunction &MF) override {
SmallVector<MachineInstr *> deletedInstrPtr;
bool Changed = false;

for (auto &MBB : MF) {
for (auto MI = MBB.begin(); MI != MBB.end(); ++MI) {
if (MI->getOpcode() == X86::MULPDrr) {
Changed = processInstruction(MF, MBB, MI, deletedInstrPtr) || Changed;
}
}
}

for (auto it : deletedInstrPtr)
it->eraseFromParent();

return Changed;
}

private:
bool processInstruction(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
SmallVector<MachineInstr *> &deletedInstrPtr) {
Register Reg = MI->getOperand(0).getReg();

for (auto NextMI = std::next(MI); NextMI != MBB.end(); ++NextMI) {
if (NextMI->getOpcode() == X86::ADDPDrr && isRegInOperands(NextMI, Reg)) {
if (!hasDependency(NextMI, Reg, MBB)) {
buildNewInstruction(MF, MBB, MI, NextMI, Reg);
deletedInstrPtr.push_back(&*MI);
deletedInstrPtr.push_back(&*NextMI);
return true;
}
break;
} else if (isRegInOperands(NextMI, Reg)) {
break;
}
}

return false;
}

bool isRegInOperands(MachineBasicBlock::iterator MI, Register Reg) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).getReg() == Reg) {
return true;
}
}
return false;
}

bool hasDependency(MachineBasicBlock::iterator NextMI, Register Reg,
MachineBasicBlock &MBB) {
if (NextMI->getOperand(0).getReg() != Reg) {
for (auto CheckMI = std::next(NextMI); CheckMI != MBB.end(); ++CheckMI) {
if (isRegInOperands(CheckMI, Reg)) {
return true;
}
}
}
if (NextMI->getOperand(1).getReg() == Reg &&
NextMI->getOperand(2).getReg() == Reg) {
return true;
}
return false;
}

void buildNewInstruction(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
MachineBasicBlock::iterator NextMI, Register Reg) {
MachineInstrBuilder BuilderMI =
BuildMI(MBB, MI, MI->getDebugLoc(),
MF.getSubtarget().getInstrInfo()->get(X86::VFMADD213PDr));
BuilderMI.addReg(NextMI->getOperand(0).getReg(), RegState::Define);
BuilderMI.addReg(MI->getOperand(1).getReg());
BuilderMI.addReg(MI->getOperand(2).getReg());
BuilderMI.addReg(NextMI->getOperand(2).getReg());
}
};

char MortinaMulAddPass::ID = 0;
static RegisterPass<MortinaMulAddPass> X("x86-mortina-muladd-pass",
"x86 Mortina Intrinsics Pass");
} // namespace
277 changes: 277 additions & 0 deletions llvm/test/lab3/mortina_nastya/test.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
# RUN: llc -mtriple x86_64-unknown-linux-gnu --load=%llvmshlibdir/X86MortinaMulAddPass%shlibext -run-pass=x86-mortina-muladd-pass %s -o - | FileCheck %s

# __m128d test1(__m128d x, __m128d y, __m128d z) {
# __m128d res = x * y + z;
# return res;
# }

# __m128d test2(__m128d x, __m128d y, __m128d z) {
# __m128d tmp = x * z + y;
# return tmp * z + y;
# }

# __m128d test3(__m128d x, __m128d y, __m128d z) {
# __m128d tmp = x * z;
# tmp = tmp / y;
# return tmp + y;
# }

# __m128d test4(__m128d x, __m128d y, __m128d z) {
# __m128d tmp = x * y;
# __m128d tmp2 = y + x - z;
# return tmp + z + tmp2;
# }

# __m128d test5(__m128d x, __m128d y, __m128d z) {
# __m128d tmp = x * y;
# __m128d tmp2 = tmp + z;
# return tmp * z;
# }

# __m128d test6(__m128d x, __m128d y) {
# __m128d tmp = x * y;
# return tmp + tmp;
# }


--- |
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) uwtable
define dso_local noundef <2 x double> @_Z5test1Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #0 {
entry:
%0 = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %x, <2 x double> %y, <2 x double> %z)
ret <2 x double> %0
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>) #1

; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) uwtable
define dso_local noundef <2 x double> @_Z5test2Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #0 {
entry:
%0 = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %x, <2 x double> %z, <2 x double> %y)
%1 = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %0, <2 x double> %z, <2 x double> %y)
ret <2 x double> %1
}

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
define dso_local noundef <2 x double> @_Z5test3Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #2 {
entry:
%mul = fmul <2 x double> %x, %z
%div = fdiv <2 x double> %mul, %y
%add = fadd <2 x double> %div, %y
ret <2 x double> %add
}

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
define dso_local noundef <2 x double> @_Z5test4Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #2 {
entry:
%mul = fmul <2 x double> %x, %y
%add = fadd <2 x double> %x, %y
%sub = fsub <2 x double> %add, %z
%add1 = fadd <2 x double> %mul, %z
%add2 = fadd <2 x double> %add1, %sub
ret <2 x double> %add2
}

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
define dso_local noundef <2 x double> @_Z5test5Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #2 {
entry:
%mul = fmul <2 x double> %x, %y
%mul1 = fmul <2 x double> %mul, %z
ret <2 x double> %mul1
}

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
define dso_local noundef <2 x double> @_Z5test6Dv2_dS_(<2 x double> noundef %x, <2 x double> noundef %y) local_unnamed_addr #2 {
entry:
%mul = fmul <2 x double> %x, %y
%add = fadd <2 x double> %mul, %mul
ret <2 x double> %add
}

attributes #0 = { mustprogress nofree nosync nounwind willreturn memory(none) uwtable "min-legal-vector-width"="128" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #2 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "min-legal-vector-width"="128" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}

...
---
name: _Z5test1Dv2_dS_S_
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
tracksDebugUserValues: true
liveins:
- { reg: '$xmm0' }
- { reg: '$xmm1' }
- { reg: '$xmm2' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo: {}
body: |
bb.0.entry:
liveins: $xmm0, $xmm1, $xmm2

renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr
RET64 $xmm0

; CHECK: $xmm0 = VFMADD213PDr $xmm0, $xmm1, $xmm2, implicit $mxcsr
; CHECK-NEXT: RET64 $xmm0

...
---
name: _Z5test2Dv2_dS_S_
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
tracksDebugUserValues: true
liveins:
- { reg: '$xmm0' }
- { reg: '$xmm1' }
- { reg: '$xmm2' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo: {}
body: |
bb.0.entry:
liveins: $xmm0, $xmm1, $xmm2

renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, renamable $xmm2, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
RET64 $xmm0

; CHECK: $xmm0 = VFMADD213PDr $xmm0, $xmm2, $xmm1, implicit $mxcsr
; CHECK-NEXT: $xmm0 = VFMADD213PDr $xmm0, $xmm2, $xmm1, implicit $mxcsr
; CHECK-NEXT: RET64 $xmm0

...
---
name: _Z5test3Dv2_dS_S_
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
tracksDebugUserValues: true
liveins:
- { reg: '$xmm0' }
- { reg: '$xmm1' }
- { reg: '$xmm2' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo: {}
body: |
bb.0.entry:
liveins: $xmm0, $xmm1, $xmm2

renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr
renamable $xmm0 = nofpexcept DIVPDrr killed renamable $xmm0, renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
RET64 $xmm0

; CHECK: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept DIVPDrr killed renamable $xmm0, renamable $xmm1, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
; CHECK-NEXT: RET64 $xmm0

...
---
name: _Z5test4Dv2_dS_S_
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
tracksDebugUserValues: true
liveins:
- { reg: '$xmm0' }
- { reg: '$xmm1' }
- { reg: '$xmm2' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo: {}
body: |
bb.0.entry:
liveins: $xmm0, $xmm1, $xmm2

$xmm3 = MOVAPDrr $xmm0
renamable $xmm3 = nofpexcept MULPDrr killed renamable $xmm3, renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept SUBPDrr killed renamable $xmm0, renamable $xmm2, implicit $mxcsr
renamable $xmm3 = nofpexcept ADDPDrr killed renamable $xmm3, killed renamable $xmm2, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm3, implicit $mxcsr
RET64 $xmm0

; CHECK: $xmm3 = MOVAPDrr $xmm0
; CHECK-NEXT: $xmm3 = VFMADD213PDr $xmm3, $xmm1, $xmm2, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept SUBPDrr killed renamable $xmm0, renamable $xmm2, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm3, implicit $mxcsr
; CHECK-NEXT: RET64 $xmm0

...
---
name: _Z5test5Dv2_dS_S_
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
tracksDebugUserValues: true
liveins:
- { reg: '$xmm0' }
- { reg: '$xmm1' }
- { reg: '$xmm2' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo: {}
body: |
bb.0.entry:
liveins: $xmm0, $xmm1, $xmm2

renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr
RET64 $xmm0

; CHECK: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr
; CHECK-NEXT: RET64 $xmm0

...
---
name: _Z5test6Dv2_dS_
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
tracksDebugUserValues: true
liveins:
- { reg: '$xmm0' }
- { reg: '$xmm1' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo: {}
body: |
bb.0.entry:
liveins: $xmm0, $xmm1

renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, renamable $xmm0, implicit $mxcsr
RET64 $xmm0

; CHECK: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, renamable $xmm0, implicit $mxcsr
; CHECK-NEXT: RET64 $xmm0

...
Loading