[PATCH] [llgo] irgen: fix canAvoid*

Andrew Wilkins axwalk at gmail.com
Tue Dec 16 01:32:57 PST 2014


Hi pcc,

canAvoidElementLoad and canAvoidLoad were incorrectly
eliding loads when an index expression is used as an
another array index expression. This led to a panic.

See comments on https://github.com/go-llvm/llgo/issues/175

http://reviews.llvm.org/D6676

Files:
  irgen/ssa.go
  test/irgen/avoidload.go

Index: irgen/ssa.go
===================================================================
--- irgen/ssa.go
+++ irgen/ssa.go
@@ -663,7 +663,7 @@
 		return value
 	}
 
-	panic("Instruction not visited yet")
+	panic(fmt.Errorf("Instruction %q not visited yet", v.Name()))
 }
 
 func (fr *frame) llvmvalue(v ssa.Value) llvm.Value {
@@ -696,11 +696,14 @@
 	}
 }
 
-func (fr *frame) canAvoidElementLoad(refs []ssa.Instruction) bool {
-	for _, ref := range refs {
-		switch ref.(type) {
-		case *ssa.Field, *ssa.Index:
-			// ok
+func (fr *frame) canAvoidElementLoad(ptr ssa.Value) bool {
+	for _, ref := range *ptr.Referrers() {
+		switch ref := ref.(type) {
+		case *ssa.Field:
+		case *ssa.Index:
+			if ref.X != ptr {
+				return false
+			}
 		default:
 			return false
 		}
@@ -724,11 +727,14 @@
 	// We only know how to avoid loads if they are used to create an interface
 	// or read an element of the structure. If we see any other referrer, abort.
 	for _, ref := range *instr.Referrers() {
-		switch ref.(type) {
+		switch ref := ref.(type) {
 		case *ssa.MakeInterface:
 			esc = true
-		case *ssa.Field, *ssa.Index:
-			// ok
+		case *ssa.Field:
+		case *ssa.Index:
+			if ref.X != instr {
+				return false
+			}
 		default:
 			return false
 		}
@@ -895,7 +901,7 @@
 		fieldtyp := instr.Type()
 		if p, ok := fr.ptr[instr.X]; ok {
 			field := fr.builder.CreateStructGEP(p, instr.Field, instr.Name())
-			if fr.canAvoidElementLoad(*instr.Referrers()) {
+			if fr.canAvoidElementLoad(instr) {
 				fr.ptr[instr] = field
 			} else {
 				fr.env[instr] = newValue(fr.builder.CreateLoad(field, ""), fieldtyp)
@@ -959,7 +965,7 @@
 		fr.condBrRuntimeError(cond, gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS)
 
 		addr := fr.builder.CreateGEP(arrayptr, []llvm.Value{zero, index}, "")
-		if fr.canAvoidElementLoad(*instr.Referrers()) {
+		if fr.canAvoidElementLoad(instr) {
 			fr.ptr[instr] = addr
 		} else {
 			fr.env[instr] = newValue(fr.builder.CreateLoad(addr, ""), instr.Type())
Index: test/irgen/avoidload.go
===================================================================
--- /dev/null
+++ test/irgen/avoidload.go
@@ -0,0 +1,15 @@
+// RUN: llgo -S -emit-llvm -o - %s | FileCheck %s
+
+package foo
+
+type X struct {
+	indices [1]int
+}
+
+// CHECK-NOT: load [200 x i64]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}, i64 160000, i32 1, i1 false)
+var _ = [100][200]int{}[0][0]
+
+// CHECK-NOT: load [1024 x i64]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}, i64 8192, i32 1, i1 false)
+var _ = [1024]int{}[X{}.indices[0]]

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D6676.17322.patch
Type: text/x-patch
Size: 2552 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141216/157367d5/attachment.bin>


More information about the llvm-commits mailing list