Skip to content

Commit 1fe31c8

Browse files
esukhovigcbot
authored andcommitted
Vectorizer update FDIV insturctions enabled
Support for FDIV insturctions inside IGCVectorizer has been added. We only support FDIV that is converted to INV, due to current emitter.
1 parent c3980c3 commit 1fe31c8

File tree

8 files changed

+356
-9
lines changed

8 files changed

+356
-9
lines changed

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4592,7 +4592,7 @@ void EmitPass::Mul64(CVariable* dst, CVariable* src[2], SIMDMode simdMode, bool
45924592
m_encoder->Push();
45934593
}
45944594

4595-
static unsigned int getVectorSize(Instruction *I) {
4595+
static unsigned int getVectorSize(Value *I) {
45964596
IGCLLVM::FixedVectorType *VecType =
45974597
llvm::dyn_cast<IGCLLVM::FixedVectorType>(I->getType());
45984598
if (!VecType)
@@ -4663,7 +4663,9 @@ void EmitPass::Add(const SSource sources[2], const DstModifier& modifier)
46634663
else
46644664
m_encoder->SetSrcSubVar(1, i);
46654665

4666-
m_encoder->SetDstSubVar(i);
4666+
if (src[0]->IsUniform() && src[1]->IsUniform()) m_encoder->SetDstSubReg(i);
4667+
else m_encoder->SetDstSubVar(i);
4668+
46674669
m_encoder->Add(m_destination, src[0], src[1]);
46684670
m_encoder->Push();
46694671
}
@@ -4695,8 +4697,9 @@ void EmitPass::Mul(const SSource sources[2], const DstModifier& modifier)
46954697
else m_encoder->SetSrcSubVar(0, i);
46964698
if (src[1]->IsUniform()) { m_encoder->SetSrcSubReg(1, i); }
46974699
else m_encoder->SetSrcSubVar(1, i);
4700+
if (src[0]->IsUniform() && src[1]->IsUniform()) m_encoder->SetDstSubReg(i);
4701+
else m_encoder->SetDstSubVar(i);
46984702

4699-
m_encoder->SetDstSubVar(i);
47004703
m_encoder->Mul(m_destination, src[0], src[1]);
47014704
m_encoder->Push();
47024705
}
@@ -4715,8 +4718,97 @@ void EmitPass::Mul(const SSource sources[2], const DstModifier& modifier)
47154718
}
47164719
}
47174720

4721+
4722+
bool isVectorOfOnes(llvm::Value* zero) {
4723+
4724+
const auto* constVec = llvm::dyn_cast<llvm::ConstantDataVector>(zero);
4725+
if (!constVec) return false;
4726+
if (!constVec->getType()->getElementType()->isFloatTy()) return false;
4727+
4728+
unsigned numElements = constVec->getNumElements();
4729+
for (unsigned i = 0; i < numElements; i++) {
4730+
const auto* constFloat = llvm::dyn_cast<llvm::ConstantFP>(constVec->getElementAsConstant(i));
4731+
if (!constFloat) return false;
4732+
if (!constFloat->isExactlyValue(1.f)) return false;
4733+
}
4734+
4735+
return true;
4736+
}
4737+
4738+
void EmitPass::Div(const SSource sources[2], const DstModifier& modifier)
4739+
{
4740+
CVariable* src[2];
4741+
for (int i = 0; i < 2; ++i) src[i] = GetSrcVariable(sources[i]);
4742+
4743+
if (IGC_IS_FLAG_ENABLED(EnableVectorEmitter) && sources[0].value->getType()->isVectorTy() && sources[1].value->getType()->isVectorTy()) {
4744+
4745+
unsigned int VectorSize = 0;
4746+
if (llvm::isa<Instruction>(sources[0].value))
4747+
VectorSize = getVectorSize(llvm::cast<Instruction>(sources[0].value));
4748+
4749+
for (unsigned int i = 0; i < VectorSize; ++i) {
4750+
SetSourceModifiers(0, sources[0]);
4751+
SetSourceModifiers(1, sources[1]);
4752+
4753+
if (src[0]->IsUniform()) { m_encoder->SetSrcSubReg(0, i); }
4754+
else m_encoder->SetSrcSubVar(0, i);
4755+
if (src[1]->IsUniform()) { m_encoder->SetSrcSubReg(1, i); }
4756+
else m_encoder->SetSrcSubVar(1, i);
4757+
if (src[0]->IsUniform() && src[1]->IsUniform()) m_encoder->SetDstSubReg(i);
4758+
else m_encoder->SetDstSubVar(i);
4759+
4760+
m_encoder->Div(m_destination, src[0], src[1]);
4761+
m_encoder->Push();
4762+
}
4763+
}
4764+
return;
4765+
}
4766+
4767+
4768+
void EmitPass::Inv(const SSource sources[2], const DstModifier& modifier) {
4769+
4770+
if (IGC_IS_FLAG_ENABLED(EnableVectorEmitter) &&
4771+
sources[0].value->getType()->isVectorTy() &&
4772+
sources[1].value->getType()->isVectorTy()) {
4773+
4774+
unsigned int VectorSize = 0;
4775+
if (llvm::isa<Value>(sources[0].value))
4776+
VectorSize = getVectorSize(llvm::cast<Value>(sources[0].value));
4777+
4778+
CVariable* src[1];
4779+
// sources[0] got used to check that it contains all 1
4780+
src[0] = GetSrcVariable(sources[1]);
4781+
4782+
for (unsigned int i = 0; i < VectorSize; ++i) {
4783+
SetSourceModifiers(0, sources[1]);
4784+
4785+
if (src[0]->IsUniform()) {
4786+
m_encoder->SetSrcSubReg(0, i);
4787+
m_encoder->SetDstSubReg(i);
4788+
}
4789+
else {
4790+
m_encoder->SetSrcSubVar(0, i);
4791+
m_encoder->SetDstSubVar(i);
4792+
}
4793+
m_encoder->Inv(m_destination, src[0]);
4794+
m_encoder->Push();
4795+
}
4796+
}
4797+
return;
4798+
}
4799+
47184800
void EmitPass::FDiv(const SSource sources[2], const DstModifier& modifier)
47194801
{
4802+
if (IGC_IS_FLAG_ENABLED(EnableVectorEmitter) &&
4803+
sources[0].value->getType()->isVectorTy() &&
4804+
sources[1].value->getType()->isVectorTy()) {
4805+
4806+
if (isVectorOfOnes(sources[0].value)) Inv(sources, modifier);
4807+
else Div(sources,modifier);
4808+
4809+
return;
4810+
}
4811+
47204812
if (isOne(sources[0].value))
47214813
{
47224814
Unary(EOPCODE_INV, &sources[1], modifier);

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ class EmitPass : public llvm::FunctionPass
101101
void Select(const SSource sources[3], const DstModifier& modifier);
102102
void PredAdd(const SSource& pred, bool invert, const SSource sources[2], const DstModifier& modifier);
103103
void Mul(const SSource[2], const DstModifier& modifier);
104+
void Div(const SSource[2], const DstModifier& modifier);
105+
void Inv(const SSource[2], const DstModifier& modifier);
104106
void Add(const SSource[2], const DstModifier& modifier);
105107
void FPTrunc(const SSource[2], const DstModifier& modifier);
106108
void Powi(const SSource[2], const DstModifier& modifier);

IGC/Compiler/CISACodeGen/IGCVectorizer.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,30 @@ unsigned int getVectorSize(Value *I) {
179179
}
180180

181181

182+
// due to our emitter, currently we only process float fdiv's that we can
183+
// construct as INV (first operand is 1.0f);
184+
bool isFDivSafe(Instruction *I) {
185+
if (!IGC_GET_FLAG_VALUE(VectorizerAllowFDIV)) return false;
186+
auto* Binary = llvm::dyn_cast<BinaryOperator>(I);
187+
auto OpCode = Binary->getOpcode();
188+
if (!(OpCode == Instruction::FDiv && I->getType()->isFloatTy())) return false;
189+
190+
//auto* constFloat = llvm::dyn_cast<llvm::ConstantFP>(I->getOperand(0));
191+
//if (!constFloat) return false;
192+
//if (!constFloat->isExactlyValue(1.f)) return false;
193+
194+
return true;
195+
}
196+
182197
bool isBinarySafe(Instruction *I) {
183198

184199
bool Result = false;
185200
auto* Binary = llvm::dyn_cast<BinaryOperator>(I);
186201
if (Binary) {
187202
auto OpCode = Binary->getOpcode();
188-
Result |= OpCode == Instruction::FMul;
189-
Result |= OpCode == Instruction::FAdd;
203+
Result |= OpCode == Instruction::FMul;
204+
Result |= (OpCode == Instruction::FAdd && IGC_GET_FLAG_VALUE(VectorizerAllowFADD));
205+
Result |= isFDivSafe(I);
190206
}
191207
return Result;
192208
}
@@ -209,6 +225,11 @@ bool IGCVectorizer::handlePHI(VecArr &Slice, Type *VectorType) {
209225
if (!checkPHI(ScalarPhi, Slice))
210226
return false;
211227

228+
if (ScalarToVector.count(ScalarPhi)) {
229+
PRINT_LOG_NL(" PHI was vectorized before, no bother ");
230+
return true;
231+
}
232+
212233
PHINode *Phi = PHINode::Create(VectorType, 2);
213234
Phi->setName("vectorized_phi");
214235

@@ -294,6 +315,7 @@ bool IGCVectorizer::handleInsertElement(VecArr &Slice, Instruction* Final) {
294315
return false;
295316

296317
PRINT_LOG_NL("InsertElement substituted with vectorized instruction");
318+
PRINT_LOG_NL("");
297319
Value *Compare = ScalarToVector[First->getOperand(1)];
298320
*(Final->use_begin()) = Compare;
299321
return true;
@@ -302,6 +324,11 @@ bool IGCVectorizer::handleInsertElement(VecArr &Slice, Instruction* Final) {
302324

303325
InsertElementInst* IGCVectorizer::createVector(VecArr& Slice, Instruction* InsertPoint) {
304326

327+
if (llvm::isa<PHINode>(InsertPoint)) {
328+
InsertPoint = InsertPoint->getParent()->getFirstNonPHI();
329+
PRINT_LOG_NL("insertPoint moved to FirstNonPHI");
330+
}
331+
305332
llvm::Type* elementType = Slice[0]->getType();
306333
llvm::VectorType* vectorType = llvm::FixedVectorType::get(elementType, Slice.size());
307334
llvm::Value* UndefVector = llvm::UndefValue::get(vectorType);
@@ -384,6 +411,11 @@ bool IGCVectorizer::handleCastInstruction(VecArr &Slice) {
384411

385412
Instruction *First = Slice.front();
386413

414+
if (ScalarToVector.count(First)) {
415+
PRINT_LOG_NL("Cast was vectorized before by other slice");
416+
return true;
417+
}
418+
387419
unsigned int OperNum = 0;
388420
Value* Vectorized = checkOperandsToBeVectorized(First, OperNum, Slice);
389421
if (!Vectorized) Vectorized = vectorizeSlice(Slice, OperNum);
@@ -526,7 +558,7 @@ void IGCVectorizer::buildTree(VecArr &V, VecOfSlices& Chain) {
526558
PRINT_DS(" check: ", LocalVector);
527559
if (IsSame) {
528560
PRINT_LOG_NL("Pushed");
529-
Chain.push_back({ OpNum, LocalVector, CurSlice});
561+
Chain.push_back({OpNum, std::move(LocalVector), CurSlice});
530562
BFSQ.push(&Chain.back());
531563
}
532564
}
@@ -719,6 +751,7 @@ bool IGCVectorizer::runOnFunction(llvm::Function &F) {
719751
M = F.getParent();
720752
CGCtx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
721753
initializeLogFile(F);
754+
PRINT_LOG_NL("vectorizer: fadd, fdiv, fptrunc");
722755

723756
VecArr ToProcess;
724757
// we collect operands that seem promising for vectorization

IGC/Compiler/CISACodeGen/IGCVectorizer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class IGCVectorizer : public llvm::FunctionPass {
3737
Slice* Parent;
3838
};
3939

40-
typedef llvm::SmallVector<Slice, 8> VecOfSlices;
40+
typedef llvm::SmallVector<Slice, 32> VecOfSlices;
4141
typedef llvm::SmallVector<VecOfSlices, 3> Tree;
4242
typedef std::unordered_map<Instruction*, VecArr*> InstructionToSliceMap;
4343

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; REQUIRES: pvc-supported, regkeys
2+
3+
; RUN: igc_opt -S -dce -platformpvc -rev-id B -has-emulated-64-bit-insts -igc-emit-visa --regkey=DumpVISAASMToConsole=1 -simd-mode 16 < %s | FileCheck %s
4+
5+
; CHECK: .decl vectorized_binary378 v_type=G type=f num_elts=8 align=dword
6+
; CHECK: .decl V0035 v_type=G type=f num_elts=8 align=wordx32
7+
; CHECK: .decl vectorized_binary402 v_type=G type=f num_elts=128 align=wordx32
8+
; CHECK: .decl V0036 v_type=G type=f num_elts=8 align=wordx32
9+
10+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,0)<1> V0035(0,0)<0;1,0>
11+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,1)<1> V0035(0,1)<0;1,0>
12+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,2)<1> V0035(0,2)<0;1,0>
13+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,3)<1> V0035(0,3)<0;1,0>
14+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,4)<1> V0035(0,4)<0;1,0>
15+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,5)<1> V0035(0,5)<0;1,0>
16+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,6)<1> V0035(0,6)<0;1,0>
17+
; CHECK: inv (M1_NM, 1) vectorized_binary378(0,7)<1> V0035(0,7)<0;1,0>
18+
; CHECK: div (M1, 16) vectorized_binary402(0,0)<1> V0032(0,0)<1;1,0> V0036(0,0)<0;1,0>
19+
; CHECK: div (M1, 16) vectorized_binary402(1,0)<1> V0032(1,0)<1;1,0> V0036(0,1)<0;1,0>
20+
; CHECK: div (M1, 16) vectorized_binary402(2,0)<1> V0032(2,0)<1;1,0> V0036(0,2)<0;1,0>
21+
; CHECK: div (M1, 16) vectorized_binary402(3,0)<1> V0032(3,0)<1;1,0> V0036(0,3)<0;1,0>
22+
; CHECK: div (M1, 16) vectorized_binary402(4,0)<1> V0032(4,0)<1;1,0> V0036(0,4)<0;1,0>
23+
; CHECK: div (M1, 16) vectorized_binary402(5,0)<1> V0032(5,0)<1;1,0> V0036(0,5)<0;1,0>
24+
; CHECK: div (M1, 16) vectorized_binary402(6,0)<1> V0032(6,0)<1;1,0> V0036(0,6)<0;1,0>
25+
; CHECK: div (M1, 16) vectorized_binary402(7,0)<1> V0032(7,0)<1;1,0> V0036(0,7)<0;1,0>
26+
27+
define spir_kernel void @_attn_fwd(half addrspace(1)* %0, half addrspace(1)* %1, half addrspace(1)* %2, float %3, i8 addrspace(1)* %4, float addrspace(1)* %5, <8 x i32> %r0) {
28+
br label %._crit_edge
29+
30+
._crit_edge: ; preds = %._crit_edge, %6
31+
%7 = call <8 x float> @llvm.genx.GenISA.sub.group.dpas.v8f32.v8f32.v8i16.v8i32(<8 x float> zeroinitializer, <8 x i16> zeroinitializer, <8 x i32> zeroinitializer, i32 0, i32 0, i32 0, i32 0, i1 false)
32+
br i1 false, label %._crit_edge, label %8
33+
34+
8: ; preds = %._crit_edge
35+
%vectorized_binary378 = fdiv <8 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, zeroinitializer
36+
%vectorized_binary402 = fdiv <8 x float> %7, zeroinitializer
37+
%9 = bitcast <8 x float> %vectorized_binary378 to <8 x i32>
38+
call void @llvm.genx.GenISA.LSC2DBlockWrite.v8i32(i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i1 false, i1 false, i32 0, <8 x i32> %9)
39+
%10 = bitcast <8 x float> %vectorized_binary402 to <8 x i32>
40+
call void @llvm.genx.GenISA.LSC2DBlockWrite.v8i32(i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i1 false, i1 false, i32 0, <8 x i32> %10)
41+
ret void
42+
}
43+
44+
declare <8 x float> @llvm.genx.GenISA.sub.group.dpas.v8f32.v8f32.v8i16.v8i32(<8 x float>, <8 x i16>, <8 x i32>, i32, i32, i32, i32, i1)
45+
46+
declare void @llvm.genx.GenISA.LSC2DBlockWrite.v8i32(i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i1, i1, i32, <8 x i32>)
47+
48+
; uselistorder directives
49+
uselistorder void (i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i1, i1, i32, <8 x i32>)* @llvm.genx.GenISA.LSC2DBlockWrite.v8i32, { 1, 0 }
50+
51+
!igc.functions = !{!0}
52+
53+
!0 = !{void (half addrspace(1)*, half addrspace(1)*, half addrspace(1)*, float, i8 addrspace(1)*, float addrspace(1)*, <8 x i32>, <8 x i32>, i32, i32, i32, i32, i32)* bitcast (void (half addrspace(1)*, half addrspace(1)*, half addrspace(1)*, float, i8 addrspace(1)*, float addrspace(1)*, <8 x i32>)* @_attn_fwd to void (half addrspace(1)*, half addrspace(1)*, half addrspace(1)*, float, i8 addrspace(1)*, float addrspace(1)*, <8 x i32>, <8 x i32>, i32, i32, i32, i32, i32)*), !1}
54+
!1 = !{!2, !3, !16}
55+
!2 = !{!"function_type", i32 0}
56+
!3 = !{!"implicit_arg_desc", !4, !5, !6, !8, !10, !12, !14}
57+
!4 = !{i32 0}
58+
!5 = !{i32 1}
59+
!6 = !{i32 14, !7}
60+
!7 = !{!"explicit_arg_num", i32 0}
61+
!8 = !{i32 14, !9}
62+
!9 = !{!"explicit_arg_num", i32 1}
63+
!10 = !{i32 14, !11}
64+
!11 = !{!"explicit_arg_num", i32 2}
65+
!12 = !{i32 14, !13}
66+
!13 = !{!"explicit_arg_num", i32 4}
67+
!14 = !{i32 14, !15}
68+
!15 = !{!"explicit_arg_num", i32 5}
69+
!16 = !{!"sub_group_size", i32 16}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; UNSUPPORTED: system-windows
2+
; REQUIRES: regkeys
3+
4+
; RUN: igc_opt -S --igc-vectorizer -dce < %s 2>&1 | FileCheck %s
5+
6+
; CHECK: %vectorized_binary = fdiv <8 x float>
7+
8+
; ModuleID = 'reduced.ll'
9+
source_filename = "initial_test.ll"
10+
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-n8:16:32"
11+
target triple = "spir64-unknown-unknown"
12+
13+
; Function Attrs: convergent nounwind
14+
define spir_kernel void @_attn_fwd() #0 {
15+
br label %._crit_edge
16+
17+
._crit_edge: ; preds = %._crit_edge, %0
18+
%1 = phi float [ 1.000000e+00, %0 ], [ %35, %._crit_edge ]
19+
%2 = phi float [ 1.000000e+00, %0 ], [ %36, %._crit_edge ]
20+
%3 = phi float [ 1.000000e+00, %0 ], [ %37, %._crit_edge ]
21+
%4 = phi float [ 1.000000e+00, %0 ], [ %38, %._crit_edge ]
22+
%5 = phi float [ 1.000000e+00, %0 ], [ %39, %._crit_edge ]
23+
%6 = phi float [ 1.000000e+00, %0 ], [ %40, %._crit_edge ]
24+
%7 = phi float [ 1.000000e+00, %0 ], [ %41, %._crit_edge ]
25+
%8 = phi float [ 1.000000e+00, %0 ], [ %42, %._crit_edge ]
26+
%9 = call float @llvm.exp2.f32(float %1)
27+
%10 = call float @llvm.exp2.f32(float %2)
28+
%11 = call float @llvm.exp2.f32(float %3)
29+
%12 = call float @llvm.exp2.f32(float %4)
30+
%13 = call float @llvm.exp2.f32(float %5)
31+
%14 = call float @llvm.exp2.f32(float %6)
32+
%15 = call float @llvm.exp2.f32(float %7)
33+
%16 = call float @llvm.exp2.f32(float %8)
34+
%17 = fdiv fast float 1.000000e+00, %9
35+
%18 = fdiv fast float 1.000000e+00, %10
36+
%19 = fdiv fast float 1.000000e+00, %11
37+
%20 = fdiv fast float 1.000000e+00, %12
38+
%21 = fdiv fast float 1.000000e+00, %13
39+
%22 = fdiv fast float 1.000000e+00, %14
40+
%23 = fdiv fast float 1.000000e+00, %15
41+
%24 = fdiv fast float 1.000000e+00, %16
42+
%25 = insertelement <8 x float> zeroinitializer, float %17, i64 0
43+
%26 = insertelement <8 x float> %25, float %18, i64 1
44+
%27 = insertelement <8 x float> %26, float %19, i64 2
45+
%28 = insertelement <8 x float> %27, float %20, i64 3
46+
%29 = insertelement <8 x float> %28, float %21, i64 4
47+
%30 = insertelement <8 x float> %29, float %22, i64 5
48+
%31 = insertelement <8 x float> %30, float %23, i64 6
49+
%32 = insertelement <8 x float> %31, float %24, i64 7
50+
%33 = call <8 x float> @llvm.genx.GenISA.sub.group.dpas.v8f32.v8f32.v8i16.v8i32(<8 x float> %32, <8 x i16> zeroinitializer, <8 x i32> zeroinitializer, i32 0, i32 0, i32 0, i32 0, i1 false)
51+
%34 = call <8 x float> @llvm.genx.GenISA.sub.group.dpas.v8f32.v8f32.v8i16.v8i32(<8 x float> %33, <8 x i16> zeroinitializer, <8 x i32> zeroinitializer, i32 0, i32 0, i32 0, i32 0, i1 false)
52+
%35 = extractelement <8 x float> %34, i64 0
53+
%36 = extractelement <8 x float> %34, i64 1
54+
%37 = extractelement <8 x float> %34, i64 2
55+
%38 = extractelement <8 x float> %34, i64 3
56+
%39 = extractelement <8 x float> %34, i64 4
57+
%40 = extractelement <8 x float> %34, i64 5
58+
%41 = extractelement <8 x float> %34, i64 6
59+
%42 = extractelement <8 x float> %34, i64 7
60+
br label %._crit_edge
61+
}
62+
63+
; Function Attrs: convergent nounwind readnone willreturn
64+
declare <8 x float> @llvm.genx.GenISA.sub.group.dpas.v8f32.v8f32.v8i16.v8i32(<8 x float>, <8 x i16>, <8 x i32>, i32, i32, i32, i32, i1) #1
65+
66+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
67+
declare float @llvm.exp2.f32(float) #2
68+
69+
; uselistorder directives
70+
uselistorder <8 x float> (<8 x float>, <8 x i16>, <8 x i32>, i32, i32, i32, i32, i1)* @llvm.genx.GenISA.sub.group.dpas.v8f32.v8f32.v8i16.v8i32, { 1, 0 }
71+
uselistorder float (float)* @llvm.exp2.f32, { 7, 6, 5, 4, 3, 2, 1, 0 }
72+
73+
attributes #0 = { convergent nounwind }
74+
attributes #1 = { convergent nounwind readnone willreturn }
75+
attributes #2 = { nofree nosync nounwind readnone speculatable willreturn }

0 commit comments

Comments
 (0)