[llvm] r194428 - Fix the recently added anyregcc convention to handle spilled operands.

Sean Silva silvas at purdue.edu
Mon Nov 11 19:11:13 PST 2013


   StartIdx = isPatchPoint ?
-             StartIdx + MI->getOperand(StartIdx+3).getImm() + 5 :
+             StartIdx + NumCallArgs + 5 :
              StartIdx + 2;

Magic numbers?




On Mon, Nov 11, 2013 at 5:40 PM, Andrew Trick <atrick at apple.com> wrote:

> Author: atrick
> Date: Mon Nov 11 16:40:25 2013
> New Revision: 194428
>
> URL: http://llvm.org/viewvc/llvm-project?rev=194428&view=rev
> Log:
> Fix the recently added anyregcc convention to handle spilled operands.
>
> Fixes <rdar://15432754> [JS] Assertion: "Folded a def to a non-store!"
>
> The primary purpose of anyregcc is to prevent a patchpoint's call
> arguments and return value from being spilled. They must be available
> in a register, although the calling convention does not pin the
> register. It's up to the front end to avoid using this convention for
> calls with more arguments than allocatable registers.
>

What happens otherwise? UB? Do we expose an API to indicate the maximum
number available? This sounds ripe for turning into an exploitable
vulnerability without some way for the API user to check their assumptions
about how many registers LLVM will provide them with.

Also, btw, anyregcc is not documented in LangRef. Please update the
documentation.

-- Sean Silva


>
> Modified:
>     llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
>     llvm/trunk/test/CodeGen/X86/anyregcc.ll
>
> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=194428&r1=194427&r2=194428&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Nov 11 16:40:25 2013
> @@ -4207,10 +4207,19 @@ static MachineInstr* foldPatchpoint(Mach
>    MachineInstrBuilder MIB(MF, NewMI);
>
>    bool isPatchPoint = MI->getOpcode() == TargetOpcode::PATCHPOINT;
> +  // For PatchPoint, the call args are not foldable.
> +  unsigned NumCallArgs = MI->getOperand(StartIdx+3).getImm();
>    StartIdx = isPatchPoint ?
> -             StartIdx + MI->getOperand(StartIdx+3).getImm() + 5 :
> +             StartIdx + NumCallArgs + 5 :
>               StartIdx + 2;
>
> +  // Return false if any operands requested for folding are not foldable
> (not
> +  // part of the stackmap's live values).
> +  for (SmallVectorImpl<unsigned>::const_iterator I = Ops.begin(), E =
> Ops.end();
> +       I != E; ++I) {
> +    if (*I < StartIdx)
> +      return 0;
> +  }
>    // No need to fold return, the meta data, and function arguments
>    for (unsigned i = 0; i < StartIdx; ++i)
>      MIB.addOperand(MI->getOperand(i));
>
> Modified: llvm/trunk/test/CodeGen/X86/anyregcc.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/anyregcc.ll?rev=194428&r1=194427&r2=194428&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/anyregcc.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/anyregcc.ll Mon Nov 11 16:40:25 2013
> @@ -8,11 +8,11 @@
>  ; Num Constants
>  ; CHECK-NEXT:   .long   0
>  ; Num Callsites
> -; CHECK-NEXT:   .long   6
> +; CHECK-NEXT:   .long   7
>
>  ; test
>  ; CHECK-NEXT:   .long   0
> -; CHECK-NEXT:   .long   L{{.*}}-_test
> +; CHECK-LABEL:  .long   L{{.*}}-_test
>  ; CHECK-NEXT:   .short  0
>  ; 3 locations
>  ; CHECK-NEXT:   .short  3
> @@ -39,7 +39,7 @@ entry:
>
>  ; property access 1 - %obj is an anyreg call argument and should
> therefore be in a register
>  ; CHECK-NEXT:   .long   1
> -; CHECK-NEXT:   .long   L{{.*}}-_property_access1
> +; CHECK-LABEL:  .long   L{{.*}}-_property_access1
>  ; CHECK-NEXT:   .short  0
>  ; 2 locations
>  ; CHECK-NEXT:   .short  2
> @@ -62,7 +62,7 @@ entry:
>
>  ; property access 2 - %obj is an anyreg call argument and should
> therefore be in a register
>  ; CHECK-NEXT:   .long   2
> -; CHECK-NEXT:   .long   L{{.*}}-_property_access2
> +; CHECK-LABEL:  .long   L{{.*}}-_property_access2
>  ; CHECK-NEXT:   .short  0
>  ; 2 locations
>  ; CHECK-NEXT:   .short  2
> @@ -86,7 +86,7 @@ entry:
>
>  ; property access 3 - %obj is a frame index
>  ; CHECK-NEXT:   .long   3
> -; CHECK-NEXT:   .long   L{{.*}}-_property_access3
> +; CHECK-LABEL:  .long   L{{.*}}-_property_access3
>  ; CHECK-NEXT:   .short  0
>  ; 2 locations
>  ; CHECK-NEXT:   .short  2
> @@ -110,7 +110,7 @@ entry:
>
>  ; anyreg_test1
>  ; CHECK-NEXT:   .long   4
> -; CHECK-NEXT:   .long   L{{.*}}-_anyreg_test1
> +; CHECK-LABEL:  .long   L{{.*}}-_anyreg_test1
>  ; CHECK-NEXT:   .short  0
>  ; 14 locations
>  ; CHECK-NEXT:   .short  14
> @@ -193,7 +193,7 @@ entry:
>
>  ; anyreg_test2
>  ; CHECK-NEXT:   .long   5
> -; CHECK-NEXT:   .long   L{{.*}}-_anyreg_test2
> +; CHECK-LABEL:  .long   L{{.*}}-_anyreg_test2
>  ; CHECK-NEXT:   .short  0
>  ; 14 locations
>  ; CHECK-NEXT:   .short  14
> @@ -274,6 +274,35 @@ entry:
>    ret i64 %ret
>  }
>
> +; Test spilling the return value of an anyregcc call.
> +;
> +; <rdar://problem/15432754> [JS] Assertion: "Folded a def to a non-store!"
> +;
> +; CHECK-LABEL: .long 12
> +; CHECK-LABEL: .long L{{.*}}-_patchpoint_spilldef
> +; CHECK-NEXT: .short 0
> +; CHECK-NEXT: .short 3
> +; Loc 0: Register (some register that will be spilled to the stack)
> +; CHECK-NEXT: .byte  1
> +; CHECK-NEXT: .byte  0
> +; CHECK-NEXT: .short {{[0-9]+}}
> +; CHECK-NEXT: .long  0
> +; Loc 1: Register RDI
> +; CHECK-NEXT: .byte  1
> +; CHECK-NEXT: .byte  0
> +; CHECK-NEXT: .short 5
> +; CHECK-NEXT: .long  0
> +; Loc 1: Register RSI
> +; CHECK-NEXT: .byte  1
> +; CHECK-NEXT: .byte  0
> +; CHECK-NEXT: .short 4
> +; CHECK-NEXT: .long  0
> +define i64 @patchpoint_spilldef(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
> +entry:
> +  %result = tail call anyregcc i64 (i32, i32, i8*, i32, ...)*
> @llvm.experimental.patchpoint.i64(i32 12, i32 15, i8* inttoptr (i64 0 to
> i8*), i32 2, i64 %p1, i64 %p2)
> +  tail call void asm sideeffect "nop",
> "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
> nounwind
> +  ret i64 %result
> +}
> +
>  declare void @llvm.experimental.patchpoint.void(i32, i32, i8*, i32, ...)
>  declare i64 @llvm.experimental.patchpoint.i64(i32, i32, i8*, i32, ...)
> -
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131111/58343425/attachment.html>


More information about the llvm-commits mailing list