No. On Xtensa (ESP32/ESP32-S3), constants that don’t fit in an instruction’s immediate field are materialized from a literal pool and fetched with L32R. A literal-pool entry is a 32-bit word, so each such constant costs 4 bytes even if the value would fit in 16 bits.
Why you’re seeing 4 bytes:
GCC emits L32R to load the constant into a register; L32R is a PC-relative 32-bit load from the pool. There’s no 16-bit “L16R” equivalent for literal pools on these cores. (Small values may be encoded with immediates like MOVI/ADDI, but once the value doesn’t fit, it becomes a pooled literal.)
What you can do instead (to actually use 16-bit storage):
Put thresholds in a table of uint16_t in .rodata (Flash) and load them at run time, instead of writing inline literals in expressions. That lets the linker pack them at 2 bytes each (modulo alignment), and the compiler can load them with 16-bit loads (l16ui) and then compare.