Home | History | Annotate | Download | only in WebAssembly
      1 ; RUN: llc < %s -asm-verbose=false -verify-machineinstrs | FileCheck %s
      2 
      3 ; Test the register stackifier pass.
      4 
      5 target datalayout = "e-p:32:32-i64:64-n32:64-S128"
      6 target triple = "wasm32-unknown-unknown"
      7 
      8 ; No because of pointer aliasing.
      9 
     10 ; CHECK-LABEL: no0:
     11 ; CHECK: return $1{{$}}
     12 define i32 @no0(i32* %p, i32* %q) {
     13   %t = load i32, i32* %q
     14   store i32 0, i32* %p
     15   ret i32 %t
     16 }
     17 
     18 ; No because of side effects.
     19 
     20 ; CHECK-LABEL: no1:
     21 ; CHECK: return $1{{$}}
     22 define i32 @no1(i32* %p, i32* dereferenceable(4) %q) {
     23   %t = load volatile i32, i32* %q, !invariant.load !0
     24   store volatile i32 0, i32* %p
     25   ret i32 %t
     26 }
     27 
     28 ; Yes because of invariant load and no side effects.
     29 
     30 ; CHECK-LABEL: yes0:
     31 ; CHECK: return $pop0{{$}}
     32 define i32 @yes0(i32* %p, i32* dereferenceable(4) %q) {
     33   %t = load i32, i32* %q, !invariant.load !0
     34   store i32 0, i32* %p
     35   ret i32 %t
     36 }
     37 
     38 ; Yes because of no intervening side effects.
     39 
     40 ; CHECK-LABEL: yes1:
     41 ; CHECK: return $pop0{{$}}
     42 define i32 @yes1(i32* %q) {
     43   %t = load volatile i32, i32* %q
     44   ret i32 %t
     45 }
     46 
     47 ; Don't schedule stack uses into the stack. To reduce register pressure, the
     48 ; scheduler might be tempted to move the definition of $2 down. However, this
     49 ; would risk getting incorrect liveness if the instructions are later
     50 ; rearranged to make the stack contiguous.
     51 
     52 ; CHECK-LABEL: stack_uses:
     53 ; CHECK-NEXT: .param i32, i32, i32, i32{{$}}
     54 ; CHECK-NEXT: .result i32{{$}}
     55 ; CHECK-NEXT: .local i32, i32{{$}}
     56 ; CHECK-NEXT: i32.const   $4=, 1{{$}}
     57 ; CHECK-NEXT: i32.const   $5=, 2{{$}}
     58 ; CHECK-NEXT: i32.lt_s    $push0=, $0, $4{{$}}
     59 ; CHECK-NEXT: i32.lt_s    $push1=, $1, $5{{$}}
     60 ; CHECK-NEXT: i32.xor     $push4=, $pop0, $pop1{{$}}
     61 ; CHECK-NEXT: i32.lt_s    $push2=, $2, $4{{$}}
     62 ; CHECK-NEXT: i32.lt_s    $push3=, $3, $5{{$}}
     63 ; CHECK-NEXT: i32.xor     $push5=, $pop2, $pop3{{$}}
     64 ; CHECK-NEXT: i32.xor     $push6=, $pop4, $pop5{{$}}
     65 ; CHECK-NEXT: i32.ne      $push7=, $pop6, $4{{$}}
     66 ; CHECK-NEXT: block       BB4_2{{$}}
     67 ; CHECK-NEXT: br_if       $pop7, BB4_2{{$}}
     68 ; CHECK-NEXT: i32.const   $push8=, 0{{$}}
     69 ; CHECK-NEXT: return      $pop8{{$}}
     70 ; CHECK-NEXT: BB4_2:
     71 ; CHECK-NEXT: return      $4{{$}}
     72 define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
     73 entry:
     74   %c = icmp sle i32 %x, 0
     75   %d = icmp sle i32 %y, 1
     76   %e = icmp sle i32 %z, 0
     77   %f = icmp sle i32 %w, 1
     78   %g = xor i1 %c, %d
     79   %h = xor i1 %e, %f
     80   %i = xor i1 %g, %h
     81   br i1 %i, label %true, label %false
     82 true:
     83   ret i32 0
     84 false:
     85   ret i32 1
     86 }
     87 
     88 !0 = !{}
     89