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