@@ -867,13 +867,104 @@ def SMRDBufferImm : ComplexPattern<iPTR, 1, "SelectSMRDBufferImm">;
867867def SMRDBufferImm32 : ComplexPattern<iPTR, 1, "SelectSMRDBufferImm32">;
868868def SMRDBufferSgprImm : ComplexPattern<iPTR, 2, "SelectSMRDBufferSgprImm">;
869869
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+
870960multiclass SMRD_Pattern <string Instr, ValueType vt, bit immci = true> {
871961
872962 // 1. IMM offset
873963 def : GCNPat <
874964 (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+ }
877968
878969 // 2. 32-bit IMM offset on CI
879970 if immci then def : GCNPat <
@@ -886,26 +977,17 @@ multiclass SMRD_Pattern <string Instr, ValueType vt, bit immci = true> {
886977 def : GCNPat <
887978 (smrd_load (SMRDSgpr i64:$sbase, i32:$soffset)),
888979 (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];
895981 }
896982
897- // 4. SGPR+IMM offset
983+ // 4. No offset
898984 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 ];
902988 }
903989
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>;
909991}
910992
911993multiclass SMLoad_Pattern <string Instr, ValueType vt, bit immci = true> {
0 commit comments