[llvm] r279239 - [Hexagon] Improvements to handling and generation of FP instructions
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 19 06:34:31 PDT 2016
Author: kparzysz
Date: Fri Aug 19 08:34:31 2016
New Revision: 279239
URL: http://llvm.org/viewvc/llvm-project?rev=279239&view=rev
Log:
[Hexagon] Improvements to handling and generation of FP instructions
Improved handling of fma, floating point min/max, additional load/store
instructions for floating point types.
Patch by Jyotsna Verma.
Added:
llvm/trunk/test/CodeGen/Hexagon/float-amode.ll
llvm/trunk/test/CodeGen/Hexagon/fminmax.ll
llvm/trunk/test/CodeGen/Hexagon/sffms.ll
Modified:
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV5.td
llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=279239&r1=279238&r2=279239&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Fri Aug 19 08:34:31 2016
@@ -2040,6 +2040,9 @@ HexagonTargetLowering::HexagonTargetLowe
setOperationAction(ISD::FSUB, MVT::f64, Expand);
setOperationAction(ISD::FMUL, MVT::f64, Expand);
+ setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
+ setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
+
setOperationAction(ISD::FP_TO_UINT, MVT::i1, Promote);
setOperationAction(ISD::FP_TO_UINT, MVT::i8, Promote);
setOperationAction(ISD::FP_TO_UINT, MVT::i16, Promote);
@@ -2287,6 +2290,10 @@ bool HexagonTargetLowering::isTruncateFr
return (VT1.getSimpleVT() == MVT::i64) && (VT2.getSimpleVT() == MVT::i32);
}
+bool HexagonTargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const {
+ return isOperationLegalOrCustom(ISD::FMA, VT);
+}
+
// Should we expand the build vector with shuffles?
bool
HexagonTargetLowering::shouldExpandBuildVectorWithShuffles(EVT VT,
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h?rev=279239&r1=279238&r2=279239&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h Fri Aug 19 08:34:31 2016
@@ -115,6 +115,12 @@ bool isPositiveHalfWord(SDNode *N);
bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
+ /// Return true if an FMA operation is faster than a pair of mul and add
+ /// instructions. fmuladd intrinsics will be expanded to FMAs when this
+ /// method returns true (and FMAs are legal), otherwise fmuladd is
+ /// expanded to mul + add.
+ bool isFMAFasterThanFMulAndFAdd(EVT) const override;
+
// Should we expand the build vector with shuffles?
bool shouldExpandBuildVectorWithShuffles(EVT VT,
unsigned DefinedValues) const override;
Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV5.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV5.td?rev=279239&r1=279238&r2=279239&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV5.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV5.td Fri Aug 19 08:34:31 2016
@@ -97,8 +97,70 @@ def S5_popcountp : ALU64_rr<(outs IntReg
let Inst{20-16} = Rss;
}
-defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>;
-defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>;
+let AddedComplexity = 20 in {
+ defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>;
+ defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>;
+}
+
+let AddedComplexity = 60 in {
+ defm : T_LoadAbsReg_Pat <load, L4_loadri_ur, f32>;
+ defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, f64>;
+}
+
+let AddedComplexity = 40 in {
+ def: Loadxs_pat<load, f32, L4_loadri_rr>;
+ def: Loadxs_pat<load, f64, L4_loadrd_rr>;
+}
+
+let AddedComplexity = 20 in {
+ def: Loadxs_simple_pat<load, f32, L4_loadri_rr>;
+ def: Loadxs_simple_pat<load, f64, L4_loadrd_rr>;
+}
+
+let AddedComplexity = 80 in {
+ def: Loada_pat<load, f32, u32ImmPred, L4_loadri_abs>;
+ def: Loada_pat<load, f32, addrga, L4_loadri_abs>;
+ def: Loada_pat<load, f64, addrga, L4_loadrd_abs>;
+}
+
+let AddedComplexity = 100 in {
+ def: LoadGP_pats <load, L2_loadrigp, f32>;
+ def: LoadGP_pats <load, L2_loadrdgp, f64>;
+}
+
+let AddedComplexity = 20 in {
+ defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
+ defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
+}
+
+// Simple patterns should be tried with the least priority.
+def: Storex_simple_pat<store, F32, S2_storeri_io>;
+def: Storex_simple_pat<store, F64, S2_storerd_io>;
+
+let AddedComplexity = 60 in {
+ defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, f32, store>;
+ defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, f64, store>;
+}
+
+let AddedComplexity = 40 in {
+ def: Storexs_pat<store, F32, S4_storeri_rr>;
+ def: Storexs_pat<store, F64, S4_storerd_rr>;
+}
+
+let AddedComplexity = 20 in {
+ def: Store_rr_pat<store, F32, S4_storeri_rr>;
+ def: Store_rr_pat<store, F64, S4_storerd_rr>;
+}
+
+let AddedComplexity = 80 in {
+ def: Storea_pat<store, F32, addrga, S2_storeriabs>;
+ def: Storea_pat<store, F64, addrga, S2_storerdabs>;
+}
+
+let AddedComplexity = 100 in {
+ def: Storea_pat<store, F32, addrgp, S2_storerigp>;
+ def: Storea_pat<store, F64, addrgp, S2_storerdgp>;
+}
defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
@@ -148,6 +210,11 @@ let Itinerary = M_tc_3x_SLOT23 in {
def F2_sfmin : T_MInstFloat < "sfmin", 0b100, 0b001>;
}
+let Predicates = [HasV5T] in {
+ def: Pat<(f32 (fminnum F32:$Rs, F32:$Rt)), (F2_sfmin F32:$Rs, F32:$Rt)>;
+ def: Pat<(f32 (fmaxnum F32:$Rs, F32:$Rt)), (F2_sfmax F32:$Rs, F32:$Rt)>;
+}
+
let AddedComplexity = 100, Predicates = [HasV5T] in {
class SfSel12<PatFrag Cmp, InstHexagon MI>
: Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rs, F32:$Rt),
@@ -166,12 +233,14 @@ let AddedComplexity = 100, Predicates =
def: SfSel21<setoge, F2_sfmin>;
}
+let Itinerary = M_tc_3or4x_SLOT23 in {
def F2_sffixupn : T_MInstFloat < "sffixupn", 0b110, 0b000>;
def F2_sffixupd : T_MInstFloat < "sffixupd", 0b110, 0b001>;
+}
// F2_sfrecipa: Reciprocal approximation for division.
-let isPredicateLate = 1, isFP = 1,
-hasSideEffects = 0, hasNewValue = 1 in
+let Uses = [USR], isPredicateLate = 1, isFP = 1,
+ hasSideEffects = 0, hasNewValue = 1, Itinerary = M_tc_3or4x_SLOT23 in
def F2_sfrecipa: MInst <
(outs IntRegs:$Rd, PredRegs:$Pe),
(ins IntRegs:$Rs, IntRegs:$Rt),
@@ -193,7 +262,7 @@ def F2_sfrecipa: MInst <
}
// F2_dfcmpeq: Floating point compare for equal.
-let isCompare = 1, isFP = 1 in
+let Uses = [USR], isCompare = 1, isFP = 1 in
class T_fcmp <string mnemonic, RegisterClass RC, bits<3> MinOp,
list<dag> pattern = [] >
: ALU64Inst <(outs PredRegs:$dst), (ins RC:$src1, RC:$src2),
@@ -484,7 +553,7 @@ let Predicates = [HasV5T] in {
}
// F2 convert template classes:
-let isFP = 1 in
+let Uses = [USR], isFP = 1 in
class F2_RDD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
string chop ="">
@@ -503,7 +572,7 @@ class F2_RDD_RSS_CONVERT<string mnemonic
let Inst{4-0} = Rdd;
}
-let isFP = 1 in
+let Uses = [USR], isFP = 1 in
class F2_RDD_RS_CONVERT<string mnemonic, bits<3> MinOp,
SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
string chop ="">
@@ -522,7 +591,7 @@ class F2_RDD_RS_CONVERT<string mnemonic,
let Inst{4-0} = Rdd;
}
-let isFP = 1, hasNewValue = 1 in
+let Uses = [USR], isFP = 1, hasNewValue = 1 in
class F2_RD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
string chop ="">
@@ -542,7 +611,7 @@ class F2_RD_RSS_CONVERT<string mnemonic,
let Inst{4-0} = Rd;
}
-let isFP = 1, hasNewValue = 1 in
+let Uses = [USR], isFP = 1, hasNewValue = 1 in
class F2_RD_RS_CONVERT<string mnemonic, bits<3> MajOp, bits<3> MinOp,
SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
string chop ="">
@@ -626,7 +695,7 @@ let AddedComplexity = 20, Predicates = [
}
// Fix up radicand.
-let isFP = 1, hasNewValue = 1 in
+let Uses = [USR], isFP = 1, hasNewValue = 1 in
def F2_sffixupr: SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs),
"$Rd = sffixupr($Rs)",
[], "" , S_2op_tc_3or4x_SLOT23>, Requires<[HasV5T]> {
@@ -650,12 +719,12 @@ let Predicates = [HasV5T] in {
}
// F2_sffma: Floating-point fused multiply add.
-let isFP = 1, hasNewValue = 1 in
+let Uses = [USR], isFP = 1, hasNewValue = 1 in
class T_sfmpy_acc <bit isSub, bit isLib>
: MInst<(outs IntRegs:$Rx),
(ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
"$Rx "#!if(isSub, "-=","+=")#" sfmpy($Rs, $Rt)"#!if(isLib, ":lib",""),
- [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
+ [], "$dst2 = $Rx" , M_tc_3or4x_SLOT23 > ,
Requires<[HasV5T]> {
bits<5> Rx;
bits<5> Rs;
@@ -681,13 +750,19 @@ def F2_sffms_lib: T_sfmpy_acc <1, 1>;
def : Pat <(fma F32:$src2, F32:$src3, F32:$src1),
(F2_sffma F32:$src1, F32:$src2, F32:$src3)>;
+def : Pat <(fma (fneg F32:$src2), F32:$src3, F32:$src1),
+ (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
+
+def : Pat <(fma F32:$src2, (fneg F32:$src3), F32:$src1),
+ (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
+
// Floating-point fused multiply add w/ additional scaling (2**pu).
-let isFP = 1, hasNewValue = 1 in
+let Uses = [USR], isFP = 1, hasNewValue = 1 in
def F2_sffma_sc: MInst <
(outs IntRegs:$Rx),
(ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt, PredRegs:$Pu),
"$Rx += sfmpy($Rs, $Rt, $Pu):scale" ,
- [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
+ [], "$dst2 = $Rx" , M_tc_3or4x_SLOT23 > ,
Requires<[HasV5T]> {
bits<5> Rx;
bits<5> Rs;
@@ -834,10 +909,10 @@ let Defs = [USR_OVF], Itinerary = S_3op_
}
// Classify floating-point value
-let isFP = 1 in
+let Uses = [USR], isFP = 1 in
def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>;
-let isFP = 1 in
+let Uses = [USR], isFP = 1 in
def F2_dfclass: ALU64Inst<(outs PredRegs:$Pd), (ins DoubleRegs:$Rss, u5Imm:$u5),
"$Pd = dfclass($Rss, #$u5)",
[], "" , ALU64_tc_2early_SLOT23 > , Requires<[HasV5T]> {
@@ -858,7 +933,7 @@ def F2_dfclass: ALU64Inst<(outs PredRegs
class T_fimm <string mnemonic, RegisterClass RC, bits<4> RegType, bit isNeg>
: ALU64Inst<(outs RC:$dst), (ins u10Imm:$src),
"$dst = "#mnemonic#"(#$src)"#!if(isNeg, ":neg", ":pos"),
- [], "", ALU64_tc_3x_SLOT23>, Requires<[HasV5T]> {
+ [], "", ALU64_tc_2_SLOT23>, Requires<[HasV5T]> {
bits<5> dst;
bits<10> src;
Modified: llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp?rev=279239&r1=279238&r2=279239&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp Fri Aug 19 08:34:31 2016
@@ -151,6 +151,7 @@ BitVector HexagonRegisterInfo::getReserv
Reserved.set(Hexagon::CS0);
Reserved.set(Hexagon::CS1);
Reserved.set(Hexagon::CS);
+ Reserved.set(Hexagon::USR);
return Reserved;
}
Added: llvm/trunk/test/CodeGen/Hexagon/float-amode.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/float-amode.ll?rev=279239&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/float-amode.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/float-amode.ll Fri Aug 19 08:34:31 2016
@@ -0,0 +1,89 @@
+; RUN: llc -march=hexagon -fp-contract=fast -disable-hexagon-peephole -disable-hexagon-amodeopt < %s | FileCheck %s
+
+; The test checks for various addressing modes for floating point loads/stores.
+
+%struct.matrix_paramsGlob = type { [50 x i8], i16, [50 x float] }
+%struct.matrix_params = type { [50 x i8], i16, float** }
+%struct.matrix_params2 = type { i16, [50 x [50 x float]] }
+
+ at globB = common global %struct.matrix_paramsGlob zeroinitializer, align 4
+ at globA = common global %struct.matrix_paramsGlob zeroinitializer, align 4
+ at b = common global float 0.000000e+00, align 4
+ at a = common global float 0.000000e+00, align 4
+
+; CHECK-LABEL: test1
+; CHECK: [[REG11:(r[0-9]+)]]{{ *}}={{ *}}memw(r{{[0-9]+}} + r{{[0-9]+}}<<#2)
+; CHECK: [[REG12:(r[0-9]+)]] += sfmpy({{.*}}[[REG11]]
+; CHECK: memw(r{{[0-9]+}} + r{{[0-9]+}}<<#2) = [[REG12]].new
+
+; Function Attrs: norecurse nounwind
+define void @test1(%struct.matrix_params* nocapture readonly %params, i32 %col1) {
+entry:
+ %matrixA = getelementptr inbounds %struct.matrix_params, %struct.matrix_params* %params, i32 0, i32 2
+ %0 = load float**, float*** %matrixA, align 4
+ %arrayidx = getelementptr inbounds float*, float** %0, i32 2
+ %1 = load float*, float** %arrayidx, align 4
+ %arrayidx1 = getelementptr inbounds float, float* %1, i32 %col1
+ %2 = load float, float* %arrayidx1, align 4
+ %mul = fmul float %2, 2.000000e+01
+ %add = fadd float %mul, 1.000000e+01
+ %arrayidx3 = getelementptr inbounds float*, float** %0, i32 5
+ %3 = load float*, float** %arrayidx3, align 4
+ %arrayidx4 = getelementptr inbounds float, float* %3, i32 %col1
+ store float %add, float* %arrayidx4, align 4
+ ret void
+}
+
+; CHECK-LABEL: test2
+; CHECK: [[REG21:(r[0-9]+)]]{{ *}}={{ *}}memw(##globB+92)
+; CHECK: [[REG22:(r[0-9]+)]] = sfadd({{.*}}[[REG21]]
+; CHECK: memw(##globA+84) = [[REG22]]
+
+; Function Attrs: norecurse nounwind
+define void @test2(%struct.matrix_params* nocapture readonly %params, i32 %col1) {
+entry:
+ %matrixA = getelementptr inbounds %struct.matrix_params, %struct.matrix_params* %params, i32 0, i32 2
+ %0 = load float**, float*** %matrixA, align 4
+ %1 = load float*, float** %0, align 4
+ %arrayidx1 = getelementptr inbounds float, float* %1, i32 %col1
+ %2 = load float, float* %arrayidx1, align 4
+ %3 = load float, float* getelementptr inbounds (%struct.matrix_paramsGlob, %struct.matrix_paramsGlob* @globB, i32 0, i32 2, i32 10), align 4
+ %add = fadd float %2, %3
+ store float %add, float* getelementptr inbounds (%struct.matrix_paramsGlob, %struct.matrix_paramsGlob* @globA, i32 0, i32 2, i32 8), align 4
+ ret void
+}
+
+; CHECK-LABEL: test3
+; CHECK: [[REG31:(r[0-9]+)]]{{ *}}={{ *}}memw(#b)
+; CHECK: [[REG32:(r[0-9]+)]] = sfadd({{.*}}[[REG31]]
+; CHECK: memw(#a) = [[REG32]]
+
+; Function Attrs: norecurse nounwind
+define void @test3(%struct.matrix_params* nocapture readonly %params, i32 %col1) {
+entry:
+ %matrixA = getelementptr inbounds %struct.matrix_params, %struct.matrix_params* %params, i32 0, i32 2
+ %0 = load float**, float*** %matrixA, align 4
+ %1 = load float*, float** %0, align 4
+ %arrayidx1 = getelementptr inbounds float, float* %1, i32 %col1
+ %2 = load float, float* %arrayidx1, align 4
+ %3 = load float, float* @b, align 4
+ %add = fadd float %2, %3
+ store float %add, float* @a, align 4
+ ret void
+}
+
+; CHECK-LABEL: test4
+; CHECK: [[REG41:(r[0-9]+)]]{{ *}}={{ *}}memw(r0<<#2 + ##globB+52)
+; CHECK: [[REG42:(r[0-9]+)]] = sfadd({{.*}}[[REG41]]
+; CHECK: memw(r0<<#2 + ##globA+60) = [[REG42]]
+; Function Attrs: noinline norecurse nounwind
+define void @test4(i32 %col1) {
+entry:
+ %arrayidx = getelementptr inbounds %struct.matrix_paramsGlob, %struct.matrix_paramsGlob* @globB, i32 0, i32 2, i32 %col1
+ %0 = load float, float* %arrayidx, align 4
+ %add = fadd float %0, 0.000000e+00
+ %add1 = add nsw i32 %col1, 2
+ %arrayidx2 = getelementptr inbounds %struct.matrix_paramsGlob, %struct.matrix_paramsGlob* @globA, i32 0, i32 2, i32 %add1
+ store float %add, float* %arrayidx2, align 4
+ ret void
+}
Added: llvm/trunk/test/CodeGen/Hexagon/fminmax.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/fminmax.ll?rev=279239&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/fminmax.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/fminmax.ll Fri Aug 19 08:34:31 2016
@@ -0,0 +1,27 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+target triple = "hexagon"
+
+; CHECK-LABEL: minimum
+; CHECK: sfmin
+define float @minimum(float %x, float %y) #0 {
+entry:
+ %call = tail call float @fminf(float %x, float %y) #1
+ ret float %call
+}
+
+; CHECK-LABEL: maximum
+; CHECK: sfmax
+define float @maximum(float %x, float %y) #0 {
+entry:
+ %call = tail call float @fmaxf(float %x, float %y) #1
+ ret float %call
+}
+
+declare float @fminf(float, float) #0
+declare float @fmaxf(float, float) #0
+
+attributes #0 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv60" "target-features"="+hvx,-hvx-double" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone }
+
Added: llvm/trunk/test/CodeGen/Hexagon/sffms.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/sffms.ll?rev=279239&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/sffms.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/sffms.ll Fri Aug 19 08:34:31 2016
@@ -0,0 +1,25 @@
+; RUN: llc -march=hexagon -fp-contract=fast < %s | FileCheck %s
+
+; Check that "Rx-=sfmpy(Rs,Rt)" is being generated for "fsub(fmul(..))"
+
+; CHECK: r{{[0-9]+}} -= sfmpy
+
+%struct.matrix_params = type { float** }
+
+; Function Attrs: norecurse nounwind
+define void @loop2_1(%struct.matrix_params* nocapture readonly %params, i32 %col1) #0 {
+entry:
+ %matrixA = getelementptr inbounds %struct.matrix_params, %struct.matrix_params* %params, i32 0, i32 0
+ %0 = load float**, float*** %matrixA, align 4
+ %1 = load float*, float** %0, align 4
+ %arrayidx1 = getelementptr inbounds float, float* %1, i32 %col1
+ %2 = load float, float* %arrayidx1, align 4
+ %arrayidx3 = getelementptr inbounds float*, float** %0, i32 %col1
+ %3 = load float*, float** %arrayidx3, align 4
+ %4 = load float, float* %3, align 4
+ %mul = fmul float %2, %4
+ %sub = fsub float %2, %mul
+ %arrayidx10 = getelementptr inbounds float, float* %3, i32 %col1
+ store float %sub, float* %arrayidx10, align 4
+ ret void
+}
More information about the llvm-commits
mailing list