blob: b49dd3ac6ed4983b549932909be5a42c66bdbf4a [file] [edit]
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c2y -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c2y -isystem %S/Inputs -DTEST_C2Y_LIB_SPELLINGS %s -emit-llvm -o - | FileCheck %s --check-prefix=C2Y
#ifndef TEST_C2Y_LIB_SPELLINGS
// N=0 and N=1: no-op, no library call or bswap emitted.
// CHECK-LABEL: test_memreverse8_const0
// CHECK-NOT: call void @stdc_memreverse8
void test_memreverse8_const0(unsigned char *p) {
__builtin_stdc_memreverse8(0, p);
}
// CHECK-LABEL: test_memreverse8_const1
// CHECK-NOT: call void @stdc_memreverse8
void test_memreverse8_const1(unsigned char *p) {
__builtin_stdc_memreverse8(1, p);
}
// N=0 and N=1 with side effects: pointer argument is evaluated but no reversal.
// CHECK-LABEL: test_memreverse8_sideeffect_n0
// CHECK: getelementptr
// CHECK: store ptr
// CHECK-NOT: call void @stdc_memreverse8
unsigned char *gp;
void test_memreverse8_sideeffect_n0(void) {
__builtin_stdc_memreverse8(0, gp++);
}
// CHECK-LABEL: test_memreverse8_sideeffect_n1
// CHECK: getelementptr
// CHECK: store ptr
// CHECK-NOT: call void @stdc_memreverse8
void test_memreverse8_sideeffect_n1(void) {
__builtin_stdc_memreverse8(1, gp++);
}
// N=2, 4, 8: lowered to a single bswap with unaligned load/store.
// CHECK-LABEL: test_memreverse8_const2
// CHECK: load i16, ptr {{.*}}, align 1
// CHECK: call i16 @llvm.bswap.i16
// CHECK: store i16 {{.*}}, ptr {{.*}}, align 1
void test_memreverse8_const2(unsigned char *p) {
__builtin_stdc_memreverse8(2, p);
}
// CHECK-LABEL: test_memreverse8_const4
// CHECK: load i32, ptr {{.*}}, align 1
// CHECK: call i32 @llvm.bswap.i32
// CHECK: store i32 {{.*}}, ptr {{.*}}, align 1
void test_memreverse8_const4(unsigned char *p) {
__builtin_stdc_memreverse8(4, p);
}
// CHECK-LABEL: test_memreverse8_const8
// CHECK: load i64, ptr {{.*}}, align 1
// CHECK: call i64 @llvm.bswap.i64
// CHECK: store i64 {{.*}}, ptr {{.*}}, align 1
void test_memreverse8_const8(unsigned char *p) {
__builtin_stdc_memreverse8(8, p);
}
// Constant N=3: not bswap-optimized, falls back to library call.
// CHECK-LABEL: test_memreverse8_const3
// CHECK: call void @stdc_memreverse8(
// CHECK-NOT: @llvm.bswap
void test_memreverse8_const3(unsigned char *p) {
__builtin_stdc_memreverse8(3, p);
}
// Runtime N: falls back to library call.
// CHECK-LABEL: test_memreverse8_runtime
// CHECK: call void @stdc_memreverse8(
void test_memreverse8_runtime(__SIZE_TYPE__ n, unsigned char *p) {
__builtin_stdc_memreverse8(n, p);
}
#endif // !TEST_C2Y_LIB_SPELLINGS
#ifdef TEST_C2Y_LIB_SPELLINGS
#include <stdbit.h>
// u8 is a no-op: single byte, nothing to swap.
// C2Y-LABEL: test_typed_memreverse8u8
// C2Y-NOT: @llvm.bswap
unsigned char test_typed_memreverse8u8(unsigned char x) {
return stdc_memreverse8u8(x);
}
// C2Y-LABEL: test_typed_memreverse8u16
// C2Y: call i16 @llvm.bswap.i16
unsigned short test_typed_memreverse8u16(unsigned short x) {
return stdc_memreverse8u16(x);
}
// C2Y-LABEL: test_typed_memreverse8u32
// C2Y: call i32 @llvm.bswap.i32
unsigned int test_typed_memreverse8u32(unsigned int x) {
return stdc_memreverse8u32(x);
}
// C2Y-LABEL: test_typed_memreverse8u64
// C2Y: call i64 @llvm.bswap.i64
__UINT64_TYPE__ test_typed_memreverse8u64(__UINT64_TYPE__ x) {
return stdc_memreverse8u64(x);
}
#endif // TEST_C2Y_LIB_SPELLINGS