On ARM/AArch64, we currently always use EmitScalarExpr for the immediate builtin arguments, instead of directly emitting the constant. When the overflow sanitizer is enabled, this generates overflow intrinsics instead of constants, breaking assumptions in various places (see PR23517).
Instead, use the knowledge of "immediates" to directly emit the constant.
I don't think there's much room for factoring out the operand emission code; if folks feel strongly I can give it another shot!
Note that the NeonEmitter changes can be simplified to the somewhat hacky:
if (hasImmediate() && getImmediateIdx() == I) { S += "I"; T.makeInteger(32, true); }
in getBuiltinTypeStr. James, which do you prefer?