@@ -867,13 +867,104 @@ def SMRDBufferImm : ComplexPattern<iPTR, 1, "SelectSMRDBufferImm">;
867
867
def SMRDBufferImm32 : ComplexPattern<iPTR, 1, "SelectSMRDBufferImm32">;
868
868
def SMRDBufferSgprImm : ComplexPattern<iPTR, 2, "SelectSMRDBufferSgprImm">;
869
869
870
+ class SMRDAlignedLoadPat<PatFrag Op> : PatFrag <(ops node:$ptr), (Op node:$ptr), [{
871
+ // Returns true if it is a naturally aligned multi-dword load.
872
+ LoadSDNode *Ld = cast<LoadSDNode>(N);
873
+ unsigned Size = Ld->getMemoryVT().getStoreSize();
874
+ return (Size <= 4) || (Ld->getAlign().value() >= PowerOf2Ceil(Size));
875
+ }]> {
876
+ let GISelPredicateCode = [{
877
+ auto &Ld = cast<GLoad>(MI);
878
+ TypeSize Size = Ld.getMMO().getSize().getValue();
879
+ return (Size <= 4) || (Ld.getMMO().getAlign().value() >= PowerOf2Ceil(Size));
880
+ }];
881
+ }
882
+
883
+ class SMRDUnalignedLoadPat<PatFrag Op> : PatFrag <(ops node:$ptr), (Op node:$ptr), [{
884
+ // Returns true if it is an under aligned multi-dword load.
885
+ LoadSDNode *Ld = cast<LoadSDNode>(N);
886
+ unsigned Size = Ld->getMemoryVT().getStoreSize();
887
+ return (Size > 4) && (Ld->getAlign().value() < PowerOf2Ceil(Size));
888
+ }]> {
889
+ let GISelPredicateCode = [{
890
+ auto &Ld = cast<GLoad>(MI);
891
+ TypeSize Size = Ld.getMMO().getSize().getValue();
892
+ return (Size > 4) && (Ld.getMMO().getAlign().value() < PowerOf2Ceil(Size));
893
+ }];
894
+ }
895
+
896
+ def alignedmultidwordload : SMRDAlignedLoadPat<smrd_load>;
897
+ def unalignedmultidwordload : SMRDUnalignedLoadPat<smrd_load>;
898
+
899
+ multiclass SMRD_Align_Pattern <string Instr, ValueType vt> {
900
+
901
+ // 1. IMM offset
902
+ def : GCNPat <
903
+ (alignedmultidwordload (SMRDImm i64:$sbase, i32:$offset)),
904
+ (vt (!cast<SM_Pseudo>(Instr#"_IMM") $sbase, $offset, 0))> {
905
+ let OtherPredicates = [isGFX8Plus];
906
+ }
907
+ def : GCNPat <
908
+ (unalignedmultidwordload (SMRDImm i64:$sbase, i32:$offset)),
909
+ (vt (!cast<SM_Pseudo>(Instr#"_IMM_ec") $sbase, $offset, 0))> {
910
+ let OtherPredicates = [isGFX8Plus];
911
+ }
912
+
913
+ // 2. SGPR offset
914
+ def : GCNPat <
915
+ (alignedmultidwordload (SMRDSgpr i64:$sbase, i32:$soffset)),
916
+ (vt (!cast<SM_Pseudo>(Instr#"_SGPR") $sbase, $soffset, 0))> {
917
+ let OtherPredicates = [isGFX8Only];
918
+ }
919
+ def : GCNPat <
920
+ (unalignedmultidwordload (SMRDSgpr i64:$sbase, i32:$soffset)),
921
+ (vt (!cast<SM_Pseudo>(Instr#"_SGPR_ec") $sbase, $soffset, 0))> {
922
+ let OtherPredicates = [isGFX8Only];
923
+ }
924
+ def : GCNPat <
925
+ (alignedmultidwordload (SMRDSgpr i64:$sbase, i32:$soffset)),
926
+ (vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") $sbase, $soffset, 0, 0))> {
927
+ let OtherPredicates = [isGFX9Plus];
928
+ }
929
+ def : GCNPat <
930
+ (unalignedmultidwordload (SMRDSgpr i64:$sbase, i32:$soffset)),
931
+ (vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM_ec") $sbase, $soffset, 0, 0))> {
932
+ let OtherPredicates = [isGFX9Plus];
933
+ }
934
+
935
+ // 3. SGPR+IMM offset
936
+ def : GCNPat <
937
+ (alignedmultidwordload (SMRDSgprImm i64:$sbase, i32:$soffset, i32:$offset)),
938
+ (vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") $sbase, $soffset, $offset, 0))> {
939
+ let OtherPredicates = [isGFX9Plus];
940
+ }
941
+ def : GCNPat <
942
+ (unalignedmultidwordload (SMRDSgprImm i64:$sbase, i32:$soffset, i32:$offset)),
943
+ (vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM_ec") $sbase, $soffset, $offset, 0))> {
944
+ let OtherPredicates = [isGFX9Plus];
945
+ }
946
+
947
+ // 4. No offset
948
+ def : GCNPat <
949
+ (vt (alignedmultidwordload (i64 SReg_64:$sbase))),
950
+ (vt (!cast<SM_Pseudo>(Instr#"_IMM") i64:$sbase, 0, 0))> {
951
+ let OtherPredicates = [isGFX8Plus];
952
+ }
953
+ def : GCNPat <
954
+ (vt (unalignedmultidwordload (i64 SReg_64:$sbase))),
955
+ (vt (!cast<SM_Pseudo>(Instr#"_IMM_ec") i64:$sbase, 0, 0))> {
956
+ let OtherPredicates = [isGFX8Plus];
957
+ }
958
+ }
959
+
870
960
multiclass SMRD_Pattern <string Instr, ValueType vt, bit immci = true> {
871
961
872
962
// 1. IMM offset
873
963
def : GCNPat <
874
964
(smrd_load (SMRDImm i64:$sbase, i32:$offset)),
875
- (vt (!cast<SM_Pseudo>(Instr#"_IMM") $sbase, $offset, 0))
876
- >;
965
+ (vt (!cast<SM_Pseudo>(Instr#"_IMM") $sbase, $offset, 0))> {
966
+ let OtherPredicates = [isGFX6GFX7];
967
+ }
877
968
878
969
// 2. 32-bit IMM offset on CI
879
970
if immci then def : GCNPat <
@@ -886,26 +977,17 @@ multiclass SMRD_Pattern <string Instr, ValueType vt, bit immci = true> {
886
977
def : GCNPat <
887
978
(smrd_load (SMRDSgpr i64:$sbase, i32:$soffset)),
888
979
(vt (!cast<SM_Pseudo>(Instr#"_SGPR") $sbase, $soffset, 0))> {
889
- let OtherPredicates = [isNotGFX9Plus];
890
- }
891
- def : GCNPat <
892
- (smrd_load (SMRDSgpr i64:$sbase, i32:$soffset)),
893
- (vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") $sbase, $soffset, 0, 0))> {
894
- let OtherPredicates = [isGFX9Plus];
980
+ let OtherPredicates = [isGFX6GFX7];
895
981
}
896
982
897
- // 4. SGPR+IMM offset
983
+ // 4. No offset
898
984
def : GCNPat <
899
- (smrd_load (SMRDSgprImm i64:$sbase, i32:$soffset, i32:$offset )),
900
- (vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM ") $sbase, $soffset, $offset , 0))> {
901
- let OtherPredicates = [isGFX9Plus ];
985
+ (vt (smrd_load ( i64 SReg_64:$sbase) )),
986
+ (vt (!cast<SM_Pseudo>(Instr#"_IMM ") i64: $sbase, 0 , 0))> {
987
+ let OtherPredicates = [isGFX6GFX7 ];
902
988
}
903
989
904
- // 5. No offset
905
- def : GCNPat <
906
- (vt (smrd_load (i64 SReg_64:$sbase))),
907
- (vt (!cast<SM_Pseudo>(Instr#"_IMM") i64:$sbase, 0, 0))
908
- >;
990
+ defm : SMRD_Align_Pattern<Instr, vt>;
909
991
}
910
992
911
993
multiclass SMLoad_Pattern <string Instr, ValueType vt, bit immci = true> {
0 commit comments