| Eric Christopher | cee313d | 2019-04-17 04:52:47 +0000 | [diff] [blame^] | 1 | ; RUN: opt -S -mergefunc < %s | FileCheck %s | 
|  | 2 |  | 
|  | 3 | ; These two functions are identical. The basic block labels are the same, and | 
|  | 4 | ; induce the same CFG. We are testing that block addresses within different | 
|  | 5 | ; functions are compared by their value, and not based on order. Both functions | 
|  | 6 | ; come from the same C-code, but in the first the two val_0/val_1 basic blocks | 
|  | 7 | ; are in a different order (they were manually switched post-compilation). | 
|  | 8 |  | 
|  | 9 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 
|  | 10 | target triple = "x86_64-unknown-linux-gnu" | 
|  | 11 |  | 
|  | 12 | define i32 @_Z1fi(i32 %i) #0 { | 
|  | 13 | entry: | 
|  | 14 | %i.addr = alloca i32, align 4 | 
|  | 15 | %ret = alloca i32, align 4 | 
|  | 16 | %l = alloca i8*, align 8 | 
|  | 17 | store i32 %i, i32* %i.addr, align 4 | 
|  | 18 | store i32 0, i32* %ret, align 4 | 
|  | 19 | store i8* blockaddress(@_Z1fi, %val_0), i8** %l, align 8 | 
|  | 20 | %0 = load i32, i32* %i.addr, align 4 | 
|  | 21 | %and = and i32 %0, 256 | 
|  | 22 | %cmp = icmp eq i32 %and, 0 | 
|  | 23 | br i1 %cmp, label %if.then, label %if.end | 
|  | 24 |  | 
|  | 25 | if.then: | 
|  | 26 | store i8* blockaddress(@_Z1fi, %val_1), i8** %l, align 8 | 
|  | 27 | br label %if.end | 
|  | 28 |  | 
|  | 29 | if.end: | 
|  | 30 | %1 = load i8*, i8** %l, align 8 | 
|  | 31 | br label %indirectgoto | 
|  | 32 |  | 
|  | 33 | val_1: | 
|  | 34 | store i32 42, i32* %ret, align 4 | 
|  | 35 | br label %end | 
|  | 36 |  | 
|  | 37 | val_0: | 
|  | 38 | store i32 12, i32* %ret, align 4 | 
|  | 39 | br label %end | 
|  | 40 |  | 
|  | 41 |  | 
|  | 42 | end: | 
|  | 43 | %2 = load i32, i32* %ret, align 4 | 
|  | 44 | ret i32 %2 | 
|  | 45 |  | 
|  | 46 | indirectgoto: | 
|  | 47 | %indirect.goto.dest = phi i8* [ %1, %if.end ] | 
|  | 48 | indirectbr i8* %indirect.goto.dest, [label %val_0, label %val_1] | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | define i32 @_Z1gi(i32 %i) #0 { | 
|  | 52 | ; CHECK-LABEL: define i32 @_Z1gi | 
|  | 53 | ; CHECK-NEXT: tail call i32 @_Z1fi | 
|  | 54 | ; CHECK-NEXT: ret | 
|  | 55 | entry: | 
|  | 56 | %i.addr = alloca i32, align 4 | 
|  | 57 | %ret = alloca i32, align 4 | 
|  | 58 | %l = alloca i8*, align 8 | 
|  | 59 | store i32 %i, i32* %i.addr, align 4 | 
|  | 60 | store i32 0, i32* %ret, align 4 | 
|  | 61 | store i8* blockaddress(@_Z1gi, %val_0), i8** %l, align 8 | 
|  | 62 | %0 = load i32, i32* %i.addr, align 4 | 
|  | 63 | %and = and i32 %0, 256 | 
|  | 64 | %cmp = icmp eq i32 %and, 0 | 
|  | 65 | br i1 %cmp, label %if.then, label %if.end | 
|  | 66 |  | 
|  | 67 | if.then: | 
|  | 68 | store i8* blockaddress(@_Z1gi, %val_1), i8** %l, align 8 | 
|  | 69 | br label %if.end | 
|  | 70 |  | 
|  | 71 | if.end: | 
|  | 72 | %1 = load i8*, i8** %l, align 8 | 
|  | 73 | br label %indirectgoto | 
|  | 74 |  | 
|  | 75 | val_0: | 
|  | 76 | store i32 12, i32* %ret, align 4 | 
|  | 77 | br label %end | 
|  | 78 |  | 
|  | 79 | val_1: | 
|  | 80 | store i32 42, i32* %ret, align 4 | 
|  | 81 | br label %end | 
|  | 82 |  | 
|  | 83 | end: | 
|  | 84 | %2 = load i32, i32* %ret, align 4 | 
|  | 85 | ret i32 %2 | 
|  | 86 |  | 
|  | 87 | indirectgoto: | 
|  | 88 | %indirect.goto.dest = phi i8* [ %1, %if.end ] | 
|  | 89 | indirectbr i8* %indirect.goto.dest, [label %val_0, label %val_1] | 
|  | 90 | } | 
|  | 91 |  |