If I understand correctly, the time range is about two months. If the time range is always lesser than a full year, you could leverage this by splitting the query in three parts merged with an UNION ALL.
(Using UNION instead of UNION ALL would cause a distinct sort operation, but we can avoid it since we know that the conditions are mutually exclusive).
DECLARE @StartDate DATE = DATEADD(m, -2, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0));
DECLARE @EndDate DATE = DATEADD(d, -2, GETDATE());
SELECT
...
WHERE YEAR(@StartDate) = YEAR (@EndDate)
AND dyear = YEAR(@StartDate)
AND dmonth BETWEEN MONTH(@StartDate) AND MONTH (@EndDate)
AND DATEFROMPARTS(dyear, dmonth, dday) BETWEEN @StartDate AND @EndDate
UNION ALL
SELECT
...
WHERE YEAR(@StartDate) < YEAR (@EndDate)
AND dyear = YEAR(@StartDate)
AND dmonth >= MONTH(@StartDate)
AND DATEFROMPARTS(dyear, dmonth, dday) >= @StartDate
UNION ALL
SELECT
...
WHERE YEAR(@StartDate) < YEAR (@EndDate)
AND dyear = YEAR(@EndDate)
AND dmonth <= MONTH(@EndDate)
AND DATEFROMPARTS(dyear, dmonth, dday) <= @EndDate
If @StartDate and @EndDate belong to the same year, only the first query will be executed, using the index for the year and month parts (the day part would never be used, since month is constrained by inequalities). The last check filters out the unwanted days.
If @StartDate and @EndDate belong to different (consecutive) years, only the last two queries will be executed, also using the index for the year and month parts.
If the date range could possibly be larger than a full year, the solution could be generalised by adding another subquery which would be executed only in the case of such greater time range:
UNION ALL
SELECT
...
WHERE YEAR(@StartDate) < YEAR(@EndDate)-1
AND dyear > YEAR(@StartDate)
AND dyear < YEAR(@EndDate)
On the other end, if you just need this exact time range (from the beginning of month, two months ago, up to two days ago), you could still use UNION ALL but with more selective conditions, which take advantage of knowing that the first month and the middle one (if exists) will be considered as whole months, while the last one will be selected up to the computed day :
DECLARE @StartDate DATE = DATEADD(m, -2, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0));
DECLARE @MiddleDate DATE = DATEADD(m, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0));
DECLARE @EndDate DATE = DATEADD(d, -2, GETDATE());
SELECT
...
WHERE dyear = YEAR(@StartDate)
AND dmonth = MONTH(@StartDate)
UNION ALL
SELECT
...
WHERE MONTH(@MiddleDate) <> MONTH(@EndDate)
AND dyear = YEAR(@MiddleDate)
AND dmonth = MONTH(@MiddleDate)
UNION ALL
SELECT
...
WHERE dyear = YEAR(@EndDate)
AND dmonth = MONTH(@EndDate)
AND dday <= DAY(@EndDate)