| Andrey Turetskiy | 9994b88 | 2016-02-20 11:11:55 +0000 | [diff] [blame^] | 1 | ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s | 
| Alexey Bataev | 7cf3247 | 2015-12-04 10:53:15 +0000 | [diff] [blame] | 2 |  | 
|  | 3 | %struct.anon1 = type { i32, i32, i32 } | 
|  | 4 | %struct.anon2 = type { i32, [32 x i32], i32 } | 
|  | 5 |  | 
|  | 6 | @arr1 = external global [65 x %struct.anon1], align 16 | 
|  | 7 | @arr2 = external global [65 x %struct.anon2], align 16 | 
|  | 8 |  | 
|  | 9 | define void @test1(i64 %x) nounwind { | 
|  | 10 | entry: | 
|  | 11 | %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0 | 
|  | 12 | %tmp = load i32, i32* %a, align 4 | 
|  | 13 | %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1 | 
|  | 14 | %tmp1 = load i32, i32* %b, align 4 | 
|  | 15 | %sub = sub i32 %tmp, %tmp1 | 
|  | 16 | %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2 | 
|  | 17 | %tmp2 = load i32, i32* %c, align 4 | 
|  | 18 | %add = add nsw i32 %sub, %tmp2 | 
|  | 19 | switch i32 %add, label %sw.epilog [ | 
|  | 20 | i32 1, label %sw.bb.1 | 
|  | 21 | i32 2, label %sw.bb.2 | 
|  | 22 | ] | 
|  | 23 |  | 
|  | 24 | sw.bb.1:                                          ; preds = %entry | 
|  | 25 | store i32 111, i32* %b, align 4 | 
|  | 26 | store i32 222, i32* %c, align 4 | 
|  | 27 | br label %sw.epilog | 
|  | 28 |  | 
|  | 29 | sw.bb.2:                                          ; preds = %entry | 
|  | 30 | store i32 333, i32* %b, align 4 | 
|  | 31 | store i32 444, i32* %c, align 4 | 
|  | 32 | br label %sw.epilog | 
|  | 33 |  | 
|  | 34 | sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry | 
|  | 35 | ret void | 
|  | 36 | ; CHECK-LABEL: test1: | 
| Dan Gohman | 0bf3ae8 | 2016-01-22 03:57:34 +0000 | [diff] [blame] | 37 | ; CHECK:	shlq $2, [[REG1:%[a-z]+]] | 
|  | 38 | ; CHECK:	movl arr1([[REG1]],[[REG1]],2), {{.*}} | 
|  | 39 | ; CHECK:	leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]] | 
|  | 40 | ; CHECK:	subl arr1+4([[REG1]],[[REG1]],2), {{.*}} | 
|  | 41 | ; CHECK:	leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]] | 
|  | 42 | ; CHECK:	addl arr1+8([[REG1]],[[REG1]],2), {{.*}} | 
| Alexey Bataev | 7cf3247 | 2015-12-04 10:53:15 +0000 | [diff] [blame] | 43 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 44 | ; CHECK:	movl ${{[1-4]+}}, ([[REG3]]) | 
|  | 45 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 46 | ; CHECK:	movl ${{[1-4]+}}, ([[REG3]]) | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | define void @test2(i64 %x) nounwind optsize { | 
|  | 50 | entry: | 
|  | 51 | %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0 | 
|  | 52 | %tmp = load i32, i32* %a, align 4 | 
|  | 53 | %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1 | 
|  | 54 | %tmp1 = load i32, i32* %b, align 4 | 
|  | 55 | %sub = sub i32 %tmp, %tmp1 | 
|  | 56 | %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2 | 
|  | 57 | %tmp2 = load i32, i32* %c, align 4 | 
|  | 58 | %add = add nsw i32 %sub, %tmp2 | 
|  | 59 | switch i32 %add, label %sw.epilog [ | 
|  | 60 | i32 1, label %sw.bb.1 | 
|  | 61 | i32 2, label %sw.bb.2 | 
|  | 62 | ] | 
|  | 63 |  | 
|  | 64 | sw.bb.1:                                          ; preds = %entry | 
|  | 65 | store i32 111, i32* %b, align 4 | 
|  | 66 | store i32 222, i32* %c, align 4 | 
|  | 67 | br label %sw.epilog | 
|  | 68 |  | 
|  | 69 | sw.bb.2:                                          ; preds = %entry | 
|  | 70 | store i32 333, i32* %b, align 4 | 
|  | 71 | store i32 444, i32* %c, align 4 | 
|  | 72 | br label %sw.epilog | 
|  | 73 |  | 
|  | 74 | sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry | 
|  | 75 | ret void | 
|  | 76 | ; CHECK-LABEL: test2: | 
| Dan Gohman | 0bf3ae8 | 2016-01-22 03:57:34 +0000 | [diff] [blame] | 77 | ; CHECK:	shlq $2, [[REG1:%[a-z]+]] | 
|  | 78 | ; CHECK:	leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]] | 
| Alexey Bataev | 7cf3247 | 2015-12-04 10:53:15 +0000 | [diff] [blame] | 79 | ; CHECK:	movl -4([[REG2]]), {{.*}} | 
|  | 80 | ; CHECK:	subl ([[REG2]]), {{.*}} | 
| Dan Gohman | 0bf3ae8 | 2016-01-22 03:57:34 +0000 | [diff] [blame] | 81 | ; CHECK:	leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]] | 
| Alexey Bataev | 7cf3247 | 2015-12-04 10:53:15 +0000 | [diff] [blame] | 82 | ; CHECK:	addl ([[REG3]]), {{.*}} | 
|  | 83 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 84 | ; CHECK:	movl ${{[1-4]+}}, ([[REG3]]) | 
|  | 85 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 86 | ; CHECK:	movl ${{[1-4]+}}, ([[REG3]]) | 
|  | 87 | } | 
|  | 88 |  | 
|  | 89 | ; Check that LEA optimization pass takes into account a resultant address | 
|  | 90 | ; displacement when choosing a LEA instruction for replacing a redundant | 
|  | 91 | ; address recalculation. | 
|  | 92 |  | 
|  | 93 | define void @test3(i64 %x) nounwind optsize { | 
|  | 94 | entry: | 
|  | 95 | %a = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 2 | 
|  | 96 | %tmp = load i32, i32* %a, align 4 | 
|  | 97 | %b = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 0 | 
|  | 98 | %tmp1 = load i32, i32* %b, align 4 | 
|  | 99 | %add = add nsw i32 %tmp, %tmp1 | 
|  | 100 | switch i32 %add, label %sw.epilog [ | 
|  | 101 | i32 1, label %sw.bb.1 | 
|  | 102 | i32 2, label %sw.bb.2 | 
|  | 103 | ] | 
|  | 104 |  | 
|  | 105 | sw.bb.1:                                          ; preds = %entry | 
|  | 106 | store i32 111, i32* %a, align 4 | 
|  | 107 | store i32 222, i32* %b, align 4 | 
|  | 108 | br label %sw.epilog | 
|  | 109 |  | 
|  | 110 | sw.bb.2:                                          ; preds = %entry | 
|  | 111 | store i32 333, i32* %a, align 4 | 
|  | 112 | store i32 444, i32* %b, align 4 | 
|  | 113 | br label %sw.epilog | 
|  | 114 |  | 
|  | 115 | sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry | 
|  | 116 | ret void | 
|  | 117 | ; CHECK-LABEL: test3: | 
|  | 118 | ; CHECK:	imulq {{.*}}, [[REG1:%[a-z]+]] | 
|  | 119 | ; CHECK:	leaq arr2+132([[REG1]]), [[REG2:%[a-z]+]] | 
|  | 120 | ; CHECK:	leaq arr2([[REG1]]), [[REG3:%[a-z]+]] | 
|  | 121 |  | 
|  | 122 | ; REG3's definition is closer to movl than REG2's, but the pass still chooses | 
|  | 123 | ; REG2 because it provides the resultant address displacement fitting 1 byte. | 
|  | 124 |  | 
|  | 125 | ; CHECK:	movl ([[REG2]]), {{.*}} | 
|  | 126 | ; CHECK:	addl ([[REG3]]), {{.*}} | 
|  | 127 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 128 | ; CHECK:	movl ${{[1-4]+}}, ([[REG3]]) | 
|  | 129 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 130 | ; CHECK:	movl ${{[1-4]+}}, ([[REG3]]) | 
|  | 131 | } | 
| Andrey Turetskiy | 1ce2c99 | 2016-01-13 11:30:44 +0000 | [diff] [blame] | 132 |  | 
|  | 133 | define void @test4(i64 %x) nounwind minsize { | 
|  | 134 | entry: | 
|  | 135 | %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0 | 
|  | 136 | %tmp = load i32, i32* %a, align 4 | 
|  | 137 | %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1 | 
|  | 138 | %tmp1 = load i32, i32* %b, align 4 | 
|  | 139 | %sub = sub i32 %tmp, %tmp1 | 
|  | 140 | %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2 | 
|  | 141 | %tmp2 = load i32, i32* %c, align 4 | 
|  | 142 | %add = add nsw i32 %sub, %tmp2 | 
|  | 143 | switch i32 %add, label %sw.epilog [ | 
|  | 144 | i32 1, label %sw.bb.1 | 
|  | 145 | i32 2, label %sw.bb.2 | 
|  | 146 | ] | 
|  | 147 |  | 
|  | 148 | sw.bb.1:                                          ; preds = %entry | 
|  | 149 | store i32 111, i32* %b, align 4 | 
|  | 150 | store i32 222, i32* %c, align 4 | 
|  | 151 | br label %sw.epilog | 
|  | 152 |  | 
|  | 153 | sw.bb.2:                                          ; preds = %entry | 
|  | 154 | store i32 333, i32* %b, align 4 | 
|  | 155 | store i32 444, i32* %c, align 4 | 
|  | 156 | br label %sw.epilog | 
|  | 157 |  | 
|  | 158 | sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry | 
|  | 159 | ret void | 
|  | 160 | ; CHECK-LABEL: test4: | 
|  | 161 | ; CHECK:	leaq arr1+4({{.*}}), [[REG2:%[a-z]+]] | 
|  | 162 | ; CHECK:	movl -4([[REG2]]), {{.*}} | 
|  | 163 | ; CHECK:	subl ([[REG2]]), {{.*}} | 
|  | 164 | ; CHECK:	addl 4([[REG2]]), {{.*}} | 
|  | 165 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 166 | ; CHECK:	movl ${{[1-4]+}}, 4([[REG2]]) | 
|  | 167 | ; CHECK:	movl ${{[1-4]+}}, ([[REG2]]) | 
|  | 168 | ; CHECK:	movl ${{[1-4]+}}, 4([[REG2]]) | 
|  | 169 | } |