block_label_names.mx raw

   1  // Regression: generated basic-block labels used to be named b1, b2, ... and
   2  // `_entry`, which share one namespace with values in LLVM IR. A parameter
   3  // named b1 therefore collided with block b1 and clang rejected the module
   4  // with "'%b1' is not a basic block" at `br label %b1`. The labels are now
   5  // dotted (bb.1, bb.entry) so no source identifier can reach them.
   6  package main
   7  
   8  import "fmt"
   9  
  10  // A parameter named exactly like the old block labels, in a function with
  11  // branches (which is what needs the generated blocks).
  12  func pick(b1 byte, b2 byte) (r int32) {
  13  	if b1 > b2 {
  14  		r = int32(b1) - int32(b2)
  15  	} else if b1 == b2 {
  16  		r = 0
  17  	} else {
  18  		r = int32(b2) - int32(b1)
  19  	}
  20  	for i := byte(0); i < b1; i++ {
  21  		r = r + int32(i)
  22  	}
  23  	return
  24  }
  25  
  26  // The entry label as a parameter name.
  27  func entry(_entry int32) (r int32) {
  28  	switch _entry {
  29  	case 0:
  30  		r = 10
  31  	case 1:
  32  		r = 20
  33  	default:
  34  		r = 30
  35  	}
  36  	return
  37  }
  38  
  39  func main() {
  40  	if got := pick(3, 1); got != 2+0+1+2 {
  41  		panic("pick(3,1)")
  42  	}
  43  	if got := pick(1, 4); got != 3 {
  44  		panic("pick(1,4)")
  45  	}
  46  	if got := pick(2, 2); got != 1 {
  47  		panic("pick(2,2)")
  48  	}
  49  	if entry(0)+entry(1)+entry(2) != 60 {
  50  		panic("entry")
  51  	}
  52  	fmt.Println("ok")
  53  }
  54