Consider this program: --- asm.c --- int G; int foo(char *p) { int rv; G = 0; asm ("" : "=r"(rv) : "r"(p) : "memory"); return rv + G; } ------------- Is the use of "memory" clobber sufficient to expect the optimizer not to optimize the "+ G" away in the return statement? I'll add here that currently it does get eliminated. This happens because in TargetLowering::getConstraintType we don't recognize the string "memory" as a memory clobber, but instead we treat it as a register clobber: if (Constraint.size() > 1 && Constraint[0] == '{' && Constraint[Constraint.size()-1] == '}') return C_Register; I can submit a patch for this issue (and some minor related things), but I'd like to know if the program itself is valid (i.e. if the clobber alone is sufficient). Here's the current dump right around lowering: *** IR Dump Before Module Verifier *** define i32 @foo(i8* %p) nounwind uwtable { entry: store i32 0, i32* @G, align 4, !tbaa !0 %0 = tail call i32 asm "", "=r,r,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %p) nounwind, !srcloc !3 %1 = load i32* @G, align 4, !tbaa !0 %add = add nsw i32 %1, %0 ret i32 %add } # *** IR Dump Before Expand ISel Pseudo-instructions ***: # Machine code for function foo: SSA Function Live Ins: %RDI in %vreg0 Function Live Outs: %EAX BB#0: derived from LLVM BB %entry Live Ins: %RDI %vreg0<def> = COPY %RDI; GR64:%vreg0 MOV32mi %RIP, 1, %noreg, <ga:@G>, %noreg, 0; mem:ST4[@G](tbaa=!"int") %vreg2<def> = COPY %vreg0; GR64:%vreg2,%vreg0 INLINEASM <es:> [attdialect], $0:[regdef:GR32], %vreg1<def>, $1:[reguse:GR64], %vreg2, $2:[clobber], %EFLAGS<earlyclobber,imp-def>, <<badref>>; GR32:%vreg1 GR64:%vreg2 %EAX<def> = COPY %vreg1; GR32:%vreg1 RET # End machine code for function foo. -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
\2013/1/8 Krzysztof Parzyszek <kparzysz at codeaurora.org>:> Consider this program: > > --- asm.c --- > int G; > > int foo(char *p) { > int rv; > G = 0; > asm ("" : "=r"(rv) > : "r"(p) > : "memory"); > return rv + G; > } > ------------- > > Is the use of "memory" clobber sufficient to expect the optimizer not to > optimize the "+ G" away in the return statement?>From gcc docs: "If your assembler instructions access memory in anunpredictable fashion, add `memory' to the list of clobbered registers. This causes GCC to not keep memory values cached in registers across the assembler instruction and not optimize stores or loads to that memory. You also should add the volatile keyword if the memory affected is not listed in the inputs or outputs of the asm, as the `memory' clobber does not count as a side-effect of the asm. " -Eli
On 1/8/2013 3:52 PM, Eli Friedman wrote:> > From gcc docs: "If your assembler instructions access memory in an > unpredictable fashion, add `memory' to the list of clobbered > registers. This causes GCC to not keep memory values cached in > registers across the assembler instruction and not optimize stores or > loads to that memory. You also should add the volatile keyword if the > memory affected is not listed in the inputs or outputs of the asm, as > the `memory' clobber does not count as a side-effect of the asm. "Yes, I've read this. It's not a very precise description. If I need to make the asm "volatile", then why would I need to put "memory" in the clobber list? Shouldn't "asm volatile" be sufficient by itself? If so, then what's the point of having the clobber "memory" in the first place? -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Possibly Parallel Threads
- [LLVMdev] System call miscompilation using the fast register allocator
- [LLVMdev] Virtual register problem in X86 backend
- [LLVMdev] Missing optimization - constant parameter
- [LLVMdev] Missing optimization - constant parameter
- [LLVMdev] Missing optimization - constant parameter