1 ; This is a test of C-level conversion operations that clang lowers 2 ; into pairs of shifts. 3 4 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ 5 ; RUN: --target x8632 -i %s --args -O2 \ 6 ; RUN: | %if --need=target_X8632 --command FileCheck %s 7 8 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ 9 ; RUN: --target x8632 -i %s --args -Om1 \ 10 ; RUN: | %if --need=target_X8632 --command FileCheck %s 11 12 ; RUN: %if --need=target_ARM32 \ 13 ; RUN: --command %p2i --filetype=obj \ 14 ; RUN: --disassemble --target arm32 -i %s --args -O2 \ 15 ; RUN: | %if --need=target_ARM32 \ 16 ; RUN: --command FileCheck --check-prefix ARM32 %s 17 18 ; RUN: %if --need=target_ARM32 \ 19 ; RUN: --command %p2i --filetype=obj \ 20 ; RUN: --disassemble --target arm32 -i %s --args -Om1 \ 21 ; RUN: | %if --need=target_ARM32 \ 22 ; RUN: --command FileCheck --check-prefix ARM32 %s 23 24 ; RUN: %if --need=target_MIPS32 --need=allow_dump \ 25 ; RUN: --command %p2i --filetype=asm --assemble \ 26 ; RUN: --disassemble --target mips32 -i %s --args -O2 \ 27 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \ 28 ; RUN: --command FileCheck --check-prefix MIPS32-O2 --check-prefix MIPS32 %s 29 30 ; RUN: %if --need=target_MIPS32 --need=allow_dump \ 31 ; RUN: --command %p2i --filetype=asm --assemble \ 32 ; RUN: --disassemble --target mips32 -i %s --args -Om1 \ 33 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \ 34 ; RUN: --command FileCheck --check-prefix MIPS32-OM1 --check-prefix MIPS32 %s 35 36 @i1 = internal global [4 x i8] zeroinitializer, align 4 37 @i2 = internal global [4 x i8] zeroinitializer, align 4 38 @u1 = internal global [4 x i8] zeroinitializer, align 4 39 40 define internal void @conv1() { 41 entry: 42 %__0 = bitcast [4 x i8]* @u1 to i32* 43 %v0 = load i32, i32* %__0, align 1 44 %sext = shl i32 %v0, 24 45 %v1 = ashr i32 %sext, 24 46 %__4 = bitcast [4 x i8]* @i1 to i32* 47 store i32 %v1, i32* %__4, align 1 48 ret void 49 } 50 ; CHECK-LABEL: conv1 51 ; CHECK: shl {{.*}},0x18 52 ; CHECK: sar {{.*}},0x18 53 54 ; ARM32-LABEL: conv1 55 ; ARM32: lsl {{.*}}, #24 56 ; ARM32: asr {{.*}}, #24 57 58 define internal void @conv2() { 59 entry: 60 %__0 = bitcast [4 x i8]* @u1 to i32* 61 %v0 = load i32, i32* %__0, align 1 62 %sext1 = shl i32 %v0, 16 63 %v1 = lshr i32 %sext1, 16 64 %__4 = bitcast [4 x i8]* @i2 to i32* 65 store i32 %v1, i32* %__4, align 1 66 ret void 67 } 68 ; CHECK-LABEL: conv2 69 ; CHECK: shl {{.*}},0x10 70 ; CHECK: shr {{.*}},0x10 71 72 ; ARM32-LABEL: conv2 73 ; ARM32: lsl {{.*}}, #16 74 ; ARM32: lsr {{.*}}, #16 75 76 define internal i32 @shlImmLarge(i32 %val) { 77 entry: 78 %result = shl i32 %val, 257 79 ret i32 %result 80 } 81 ; CHECK-LABEL: shlImmLarge 82 ; CHECK: shl {{.*}},0x1 83 84 ; MIPS32-LABEL: shlImmLarge 85 ; MIPS32: sll 86 87 define internal i32 @shlImmNeg(i32 %val) { 88 entry: 89 %result = shl i32 %val, -1 90 ret i32 %result 91 } 92 ; CHECK-LABEL: shlImmNeg 93 ; CHECK: shl {{.*}},0xff 94 95 ; MIPS32-LABEL: shlImmNeg 96 ; MIPS32: sll 97 98 define internal i32 @lshrImmLarge(i32 %val) { 99 entry: 100 %result = lshr i32 %val, 257 101 ret i32 %result 102 } 103 ; CHECK-LABEL: lshrImmLarge 104 ; CHECK: shr {{.*}},0x1 105 106 ; MIPS32-LABEL: lshrImmLarge 107 ; MIPS32: srl 108 109 define internal i32 @lshrImmNeg(i32 %val) { 110 entry: 111 %result = lshr i32 %val, -1 112 ret i32 %result 113 } 114 ; CHECK-LABEL: lshrImmNeg 115 ; CHECK: shr {{.*}},0xff 116 117 ; MIPS32-LABEL: lshrImmNeg 118 ; MIPS32: srl 119 120 define internal i32 @ashrImmLarge(i32 %val) { 121 entry: 122 %result = ashr i32 %val, 257 123 ret i32 %result 124 } 125 ; CHECK-LABEL: ashrImmLarge 126 ; CHECK: sar {{.*}},0x1 127 128 ; MIPS32-LABEL: ashrImmLarge 129 ; MIPS32: sra 130 131 define internal i32 @ashrImmNeg(i32 %val) { 132 entry: 133 %result = ashr i32 %val, -1 134 ret i32 %result 135 } 136 ; CHECK-LABEL: ashrImmNeg 137 ; CHECK: sar {{.*}},0xff 138 139 ; MIPS32-LABEL: ashrImmNeg 140 ; MIPS32: sra 141 142 define internal i64 @shlImm64One(i64 %val) { 143 entry: 144 %result = shl i64 %val, 1 145 ret i64 %result 146 } 147 ; CHECK-LABEL: shlImm64One 148 ; CHECK: shl {{.*}},1 149 ; MIPS32-LABEL: shlImm64One 150 ; MIPS32: addu [[T_LO:.*]],[[VAL_LO:.*]],[[VAL_LO]] 151 ; MIPS32: sltu [[T1:.*]],[[T_LO]],[[VAL_LO]] 152 ; MIPS32: addu [[T2:.*]],[[T1]],[[VAL_HI:.*]] 153 ; MIPS32: addu {{.*}},[[VAL_HI]],[[T2]] 154 155 define internal i64 @shlImm64LessThan32(i64 %val) { 156 entry: 157 %result = shl i64 %val, 4 158 ret i64 %result 159 } 160 ; CHECK-LABEL: shlImm64LessThan32 161 ; CHECK: shl {{.*}},0x4 162 ; MIPS32-LABEL: shlImm64LessThan32 163 ; MIPS32: srl [[T1:.*]],[[VAL_LO:.*]],0x1c 164 ; MIPS32: sll [[T2:.*]],{{.*}},0x4 165 ; MIPS32: or {{.*}},[[T1]],[[T2]] 166 ; MIPS32: sll {{.*}},[[VAL_LO]],0x4 167 168 define internal i64 @shlImm64Equal32(i64 %val) { 169 entry: 170 %result = shl i64 %val, 32 171 ret i64 %result 172 } 173 ; CHECK-LABEL: shlImm64Equal32 174 ; CHECK-NOT: shl 175 ; MIPS32-LABEL: shlImm64Equal32 176 ; MIPS32: li {{.*}},0 177 ; MIPS32-O2: move 178 ; MIPS32-OM1: sw 179 ; MIPS32-OM1: lw 180 181 define internal i64 @shlImm64GreaterThan32(i64 %val) { 182 entry: 183 %result = shl i64 %val, 40 184 ret i64 %result 185 } 186 ; CHECK-LABEL: shlImm64GreaterThan32 187 ; CHECK: shl {{.*}},0x8 188 ; MIPS32-LABEL: shlImm64GreaterThan32 189 ; MIPS32: sll {{.*}},{{.*}},0x8 190 ; MIPS32: li {{.*}},0 191 192 define internal i64 @lshrImm64One(i64 %val) { 193 entry: 194 %result = lshr i64 %val, 1 195 ret i64 %result 196 } 197 ; CHECK-LABEL: lshrImm64One 198 ; CHECK: shr {{.*}},1 199 ; MIPS32-LABEL: lshrImm64One 200 ; MIPS32: sll [[T1:.*]],[[VAL_HI:.*]],0x1f 201 ; MIPS32: srl [[T2:.*]],{{.*}},0x1 202 ; MIPS32: or {{.*}},[[T1]],[[T2]] 203 ; MIPS32: srl {{.*}},[[VAL_HI]],0x1 204 205 define internal i64 @lshrImm64LessThan32(i64 %val) { 206 entry: 207 %result = lshr i64 %val, 4 208 ret i64 %result 209 } 210 ; CHECK-LABEL: lshrImm64LessThan32 211 ; CHECK: shrd {{.*}},0x4 212 ; CHECK: shr {{.*}},0x4 213 ; MIPS32-LABEL: lshrImm64LessThan32 214 ; MIPS32: sll [[T1:.*]],[[VAL_HI:.*]],0x1c 215 ; MIPS32: srl [[T2:.*]],{{.*}},0x4 216 ; MIPS32: or {{.*}},[[T1]],[[T2]] 217 ; MIPS32: srl {{.*}},[[VAL_HI]],0x4 218 219 define internal i64 @lshrImm64Equal32(i64 %val) { 220 entry: 221 %result = lshr i64 %val, 32 222 ret i64 %result 223 } 224 ; CHECK-LABEL: lshrImm64Equal32 225 ; CHECK-NOT: shr 226 ; MIPS32-LABEL: lshrImm64Equal32 227 ; MIPS32: li {{.*}},0 228 ; MIPS32-O2: move 229 ; MIPS32-OM1: sw 230 ; MIPS32-OM1: lw 231 232 define internal i64 @lshrImm64GreaterThan32(i64 %val) { 233 entry: 234 %result = lshr i64 %val, 40 235 ret i64 %result 236 } 237 ; CHECK-LABEL: lshrImm64GreaterThan32 238 ; CHECK-NOT: shrd 239 ; CHECK: shr {{.*}},0x8 240 ; MIPS32-LABEL: lshrImm64GreaterThan32 241 ; MIPS32: srl {{.*}},{{.*}},0x8 242 ; MIPS32: li {{.*}},0 243 244 define internal i64 @ashrImm64One(i64 %val) { 245 entry: 246 %result = ashr i64 %val, 1 247 ret i64 %result 248 } 249 ; CHECK-LABEL: ashrImm64One 250 ; CHECK: shrd {{.*}},0x1 251 ; CHECK: sar {{.*}},1 252 ; MIPS32-LABEL: ashrImm64One 253 ; MIPS32: sll [[T1:.*]],[[VAL_HI:.*]],0x1f 254 ; MIPS32: srl [[T2:.*]],{{.*}},0x1 255 ; MIPS32: or {{.*}},[[T1]],[[T2]] 256 ; MIPS32: sra {{.*}},[[VAL_HI]],0x1 257 258 define internal i64 @ashrImm64LessThan32(i64 %val) { 259 entry: 260 %result = ashr i64 %val, 4 261 ret i64 %result 262 } 263 ; CHECK-LABEL: ashrImm64LessThan32 264 ; CHECK: shrd {{.*}},0x4 265 ; CHECK: sar {{.*}},0x4 266 ; MIPS32-LABEL: ashrImm64LessThan32 267 ; MIPS32: sll [[T1:.*]],[[VAL_HI:.*]],0x1c 268 ; MIPS32: srl [[T2:.*]],{{.*}},0x4 269 ; MIPS32: or {{.*}},[[T1]],[[T2]] 270 ; MIPS32: sra {{.*}},[[VAL_HI]],0x4 271 272 define internal i64 @ashrImm64Equal32(i64 %val) { 273 entry: 274 %result = ashr i64 %val, 32 275 ret i64 %result 276 } 277 ; CHECK-LABEL: ashrImm64Equal32 278 ; CHECK: sar {{.*}},0x1f 279 ; CHECK-NOT: shrd 280 ; MIPS32-LABEL: ashrImm64Equal32 281 ; MIPS32: sra {{.*}},[[VAL_HI:.*]],0x1f 282 ; MIPS32-O2: move {{.*}},[[VAL_HI]] 283 ; MIPS32-OM1: sw [[VAL_HI]],{{.*}} 284 ; MIPS32-OM1: lw {{.*}},{{.*}} 285 286 define internal i64 @ashrImm64GreaterThan32(i64 %val) { 287 entry: 288 %result = ashr i64 %val, 40 289 ret i64 %result 290 } 291 ; CHECK-LABEL: ashrImm64GreaterThan32 292 ; CHECK: sar {{.*}},0x1f 293 ; CHECK: shrd {{.*}},0x8 294 ; MIPS32-LABEL: ashrImm64GreaterThan32 295 ; MIPS32: sra {{.*}},[[VAL_HI:.*]],0x8 296 ; MIPS32: sra {{.*}},[[VAL_HI]],0x1f 297