summaryrefslogtreecommitdiffstats
path: root/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/64bit-swiftcall.c93
-rw-r--r--test/CodeGen/Inputs/code-coverage-filter1.h1
-rw-r--r--test/CodeGen/Inputs/code-coverage-filter2.h1
-rw-r--r--test/CodeGen/Inputs/thinlto_backend_local_name_conflict1.ll13
-rw-r--r--test/CodeGen/Inputs/thinlto_backend_local_name_conflict2.ll13
-rw-r--r--test/CodeGen/aarch64-neon-3v.c83
-rw-r--r--test/CodeGen/aarch64-neon-across.c147
-rw-r--r--test/CodeGen/aarch64-neon-extract.c24
-rw-r--r--test/CodeGen/aarch64-neon-fma.c41
-rw-r--r--test/CodeGen/aarch64-neon-fp16fml.c196
-rw-r--r--test/CodeGen/aarch64-neon-ldst-one.c460
-rw-r--r--test/CodeGen/aarch64-neon-scalar-copy.c26
-rw-r--r--test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c43
-rw-r--r--test/CodeGen/aarch64-neon-tbl.c207
-rw-r--r--test/CodeGen/aarch64-neon-vget.c51
-rw-r--r--test/CodeGen/aarch64-poly128.c58
-rw-r--r--test/CodeGen/aarch64-poly64.c71
-rw-r--r--test/CodeGen/aarch64-sign-return-address.c31
-rw-r--r--test/CodeGen/aarch64-vpcs.c23
-rw-r--r--test/CodeGen/adc-builtins.c8
-rw-r--r--test/CodeGen/address-sanitizer-and-array-cookie.cpp2
-rw-r--r--test/CodeGen/adx-builtins.c4
-rw-r--r--test/CodeGen/arc/arguments.c135
-rw-r--r--test/CodeGen/arc/struct-align.c26
-rw-r--r--test/CodeGen/arm-neon-fma.c11
-rw-r--r--test/CodeGen/arm-neon-numeric-maxmin.c15
-rw-r--r--test/CodeGen/arm-neon-vcvtX.c51
-rw-r--r--test/CodeGen/arm64-microsoft-intrinsics.c29
-rw-r--r--test/CodeGen/arm64-microsoft-status-reg.cpp119
-rw-r--r--test/CodeGen/arm64_vdupq_n_f64.c4
-rw-r--r--test/CodeGen/asan-globals-odr.cpp30
-rw-r--r--test/CodeGen/asan-static-odr.cpp17
-rw-r--r--test/CodeGen/atomics-inlining.c3
-rw-r--r--test/CodeGen/attr-cpuspecific.c290
-rw-r--r--test/CodeGen/attr-speculative-load-hardening.c5
-rw-r--r--test/CodeGen/attr-speculative-load-hardening.cpp18
-rw-r--r--test/CodeGen/attr-speculative-load-hardening.m9
-rw-r--r--test/CodeGen/attr-target-mv-func-ptrs.c41
-rw-r--r--test/CodeGen/attr-target-mv-va-args.c53
-rw-r--r--test/CodeGen/attr-target-mv.c265
-rw-r--r--test/CodeGen/avx512bw-builtins.c30
-rw-r--r--test/CodeGen/avx512f-builtins.c40
-rw-r--r--test/CodeGen/avx512vl-builtins.c286
-rw-r--r--test/CodeGen/avx512vlbw-builtins.c48
-rw-r--r--test/CodeGen/block-byref-aggr.c4
-rw-r--r--test/CodeGen/blocks-seq.c1
-rw-r--r--test/CodeGen/builtin-constant-p.c168
-rw-r--r--test/CodeGen/builtin-cpu-supports.c9
-rw-r--r--test/CodeGen/builtin-memfns.c7
-rw-r--r--test/CodeGen/builtin-unpredictable.c12
-rw-r--r--test/CodeGen/builtins-hexagon-v66-128B.c67
-rw-r--r--test/CodeGen/builtins-hexagon-v66.c91
-rw-r--r--test/CodeGen/builtins-hexagon.c4
-rw-r--r--test/CodeGen/builtins-mips-msa-error.c759
-rw-r--r--test/CodeGen/builtins-mips-msa.c16
-rw-r--r--test/CodeGen/builtins-ppc-altivec.c156
-rw-r--r--test/CodeGen/builtins-ppc-p8vector.c12
-rw-r--r--test/CodeGen/builtins-ppc-quadword.c32
-rw-r--r--test/CodeGen/builtins-ppc-vsx.c36
-rw-r--r--test/CodeGen/builtins-wasm.c394
-rw-r--r--test/CodeGen/builtins.c52
-rw-r--r--test/CodeGen/catch-implicit-conversions-basics.c125
-rw-r--r--test/CodeGen/catch-implicit-integer-arithmetic-value-change-basics.c123
-rw-r--r--test/CodeGen/catch-implicit-integer-conversions-basics.c28
-rw-r--r--test/CodeGen/catch-implicit-integer-sign-changes-CompoundAssignOperator.c2561
-rw-r--r--test/CodeGen/catch-implicit-integer-sign-changes-basics.c157
-rw-r--r--test/CodeGen/catch-implicit-integer-sign-changes-true-negatives.c152
-rw-r--r--test/CodeGen/catch-implicit-integer-sign-changes.c273
-rw-r--r--test/CodeGen/catch-implicit-integer-truncations-CompoundAssignOperator.c2745
-rw-r--r--test/CodeGen/catch-implicit-integer-truncations-basics-negatives.c38
-rw-r--r--test/CodeGen/catch-implicit-integer-truncations-basics.c18
-rw-r--r--test/CodeGen/catch-implicit-integer-truncations.c36
-rw-r--r--test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change-CompoundAssignOperator.c2553
-rw-r--r--test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change.c152
-rw-r--r--test/CodeGen/catch-implicit-signed-integer-truncations-basics-negatives.c40
-rw-r--r--test/CodeGen/catch-implicit-signed-integer-truncations-basics.c113
-rw-r--r--test/CodeGen/catch-implicit-unsigned-integer-truncations-basics-negatives.c40
-rw-r--r--test/CodeGen/catch-implicit-unsigned-integer-truncations-basics.c109
-rw-r--r--test/CodeGen/cf-runtime-abi.c60
-rw-r--r--test/CodeGen/code-coverage-filter.c84
-rw-r--r--test/CodeGen/codemodels.c2
-rw-r--r--test/CodeGen/debug-info-abspath.c34
-rw-r--r--test/CodeGen/debug-info-compilation-dir.c4
-rw-r--r--test/CodeGen/debug-info-ranges-base-address.c9
-rw-r--r--test/CodeGen/debug-info-scope-file.c4
-rw-r--r--test/CodeGen/debug-info-vla.c4
-rw-r--r--test/CodeGen/debug-prefix-map.c32
-rw-r--r--test/CodeGen/decl.c4
-rw-r--r--test/CodeGen/designated-initializers.c14
-rw-r--r--test/CodeGen/dump-struct-builtin.c36
-rw-r--r--test/CodeGen/dwarf-version.c24
-rw-r--r--test/CodeGen/exceptions.c1
-rw-r--r--test/CodeGen/indirect-tls-seg-refs.c10
-rw-r--r--test/CodeGen/inline-asm-matching-ppc-vsx.c20
-rw-r--r--test/CodeGen/keep-static-consts.cpp7
-rw-r--r--test/CodeGen/mips-zero-sized-struct.c14
-rw-r--r--test/CodeGen/ms-intrinsics-cpuid.c18
-rw-r--r--test/CodeGen/ms-intrinsics-other.c48
-rw-r--r--test/CodeGen/ms-intrinsics-rotations.c99
-rw-r--r--test/CodeGen/ms-intrinsics.c751
-rw-r--r--test/CodeGen/ms-setjmp.c4
-rw-r--r--test/CodeGen/personality.c1
-rw-r--r--test/CodeGen/split-debug-single-file.c17
-rw-r--r--test/CodeGen/sse2-builtins.c48
-rw-r--r--test/CodeGen/stack-arg-probe.c9
-rw-r--r--test/CodeGen/swift-call-conv.c9
-rw-r--r--test/CodeGen/target-builtin-noerror.c10
-rw-r--r--test/CodeGen/target-data.c32
-rw-r--r--test/CodeGen/thinlto-distributed-cfi-devirt.ll2
-rw-r--r--test/CodeGen/thinlto_backend.ll3
-rw-r--r--test/CodeGen/thinlto_backend_local_name_conflict.ll36
-rw-r--r--test/CodeGen/ubsan-debuglog-return.c10
-rw-r--r--test/CodeGen/vector.c2
-rw-r--r--test/CodeGen/win64-i128.c16
-rw-r--r--test/CodeGen/windows-swiftcall.c77
-rw-r--r--test/CodeGen/x86-vector-width.c61
-rw-r--r--test/CodeGen/xray-attributes-supported.cpp24
117 files changed, 14238 insertions, 1606 deletions
diff --git a/test/CodeGen/64bit-swiftcall.c b/test/CodeGen/64bit-swiftcall.c
index 7486e44406..6175553ec9 100644
--- a/test/CodeGen/64bit-swiftcall.c
+++ b/test/CodeGen/64bit-swiftcall.c
@@ -10,7 +10,7 @@
#define ERROR __attribute__((swift_error_result))
#define CONTEXT __attribute__((swift_context))
-// CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, float 0.000000e+00, float 0.000000e+00 }
+// CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, i32 0, i32 0 }
/*****************************************************************************/
/****************************** PARAMETER ABIS *******************************/
@@ -102,8 +102,8 @@ typedef struct {
int x;
char c0;
char c1;
- float f0;
- float f1;
+ int f0;
+ int f1;
} struct_1;
TEST(struct_1);
// CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_1() {{.*}}{
@@ -150,8 +150,8 @@ typedef struct {
int x;
char c0;
__attribute__((aligned(2))) char c1;
- float f0;
- float f1;
+ int f0;
+ int f1;
} struct_2;
TEST(struct_2);
// CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_2() {{.*}}{
@@ -308,20 +308,30 @@ typedef union {
TEST(union_hom_fp_partial)
// CHECK: define void @test_union_hom_fp_partial()
// CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16
-// CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_union_hom_fp_partial()
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 0
-// CHECK: store i64 [[T1]], i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 1
-// CHECK: store i64 [[T1]], i64* [[T0]], align 8
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
-// CHECK: [[V0:%.*]] = load i64, i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[V1:%.*]] = load i64, i64* [[T0]], align 8
-// CHECK: call swiftcc void @take_union_hom_fp_partial(i64 [[V0]], i64 [[V1]])
+// CHECK: [[CALL:%.*]] = call swiftcc { float, float, float, float } @return_union_hom_fp_partial()
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { float, float, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 0
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 0
+// CHECK: store float [[T1]], float* [[T0]], align 16
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 1
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 2
+// CHECK: store float [[T1]], float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 3
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 3
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { float, float, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 0
+// CHECK: [[V0:%.*]] = load float, float* [[T0]], align 16
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[V1:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[V2:%.*]] = load float, float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 3
+// CHECK: [[V3:%.*]] = load float, float* [[T0]], align 4
+// CHECK: call swiftcc void @take_union_hom_fp_partial(float [[V0]], float [[V1]], float [[V2]], float [[V3]])
// CHECK: ret void
// CHECK: }
@@ -332,20 +342,25 @@ typedef union {
TEST(union_het_fpv_partial)
// CHECK-LABEL: define void @test_union_het_fpv_partial()
// CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16
-// CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_union_het_fpv_partial()
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 0
+// CHECK: [[CALL:%.*]] = call swiftcc { i64, float, float } @return_union_het_fpv_partial()
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 0
+// CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 0
// CHECK: store i64 [[T1]], i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 1
-// CHECK: store i64 [[T1]], i64* [[T0]], align 8
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 1
+// CHECK: store float [[T1]], float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 2
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 0
// CHECK: [[V0:%.*]] = load i64, i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[V1:%.*]] = load i64, i64* [[T0]], align 8
-// CHECK: call swiftcc void @take_union_het_fpv_partial(i64 [[V0]], i64 [[V1]])
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[V1:%.*]] = load float, float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[V2:%.*]] = load float, float* [[T0]], align 4
+// CHECK: call swiftcc void @take_union_het_fpv_partial(i64 [[V0]], float [[V1]], float [[V2]])
// CHECK: ret void
// CHECK: }
@@ -464,8 +479,8 @@ typedef struct {
float f1;
} struct_f2;
TEST(struct_f2)
-// CHECK-LABEL: define swiftcc i64 @return_struct_f2()
-// CHECK-LABEL: define swiftcc void @take_struct_f2(i64)
+// CHECK-LABEL: define swiftcc { float, float } @return_struct_f2()
+// CHECK-LABEL: define swiftcc void @take_struct_f2(float, float)
typedef struct {
float f0;
@@ -473,8 +488,8 @@ typedef struct {
float f2;
} struct_f3;
TEST(struct_f3)
-// CHECK-LABEL: define swiftcc { i64, float } @return_struct_f3()
-// CHECK-LABEL: define swiftcc void @take_struct_f3(i64, float)
+// CHECK-LABEL: define swiftcc { float, float, float } @return_struct_f3()
+// CHECK-LABEL: define swiftcc void @take_struct_f3(float, float, float)
typedef struct {
float f0;
@@ -483,8 +498,8 @@ typedef struct {
float f3;
} struct_f4;
TEST(struct_f4)
-// CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_f4()
-// CHECK-LABEL: define swiftcc void @take_struct_f4(i64, i64)
+// CHECK-LABEL: define swiftcc { float, float, float, float } @return_struct_f4()
+// CHECK-LABEL: define swiftcc void @take_struct_f4(float, float, float, float)
typedef struct {
@@ -1016,8 +1031,8 @@ typedef union {
float3 fv2;
} union_hom_fp_partial2;
TEST(union_hom_fp_partial2)
-// X86-64-LABEL: take_union_hom_fp_partial2(i64, float)
-// ARM64-LABEL: take_union_hom_fp_partial2(i64, float)
+// X86-64-LABEL: take_union_hom_fp_partial2(float, float, float)
+// ARM64-LABEL: take_union_hom_fp_partial2(float, float, float)
// At one point, we emitted lifetime.ends without a matching lifetime.start for
// CoerceAndExpanded args. Since we're not performing optimizations, neither
diff --git a/test/CodeGen/Inputs/code-coverage-filter1.h b/test/CodeGen/Inputs/code-coverage-filter1.h
new file mode 100644
index 0000000000..4c0de6c5e5
--- /dev/null
+++ b/test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
diff --git a/test/CodeGen/Inputs/code-coverage-filter2.h b/test/CodeGen/Inputs/code-coverage-filter2.h
new file mode 100644
index 0000000000..91e68ccae9
--- /dev/null
+++ b/test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
diff --git a/test/CodeGen/Inputs/thinlto_backend_local_name_conflict1.ll b/test/CodeGen/Inputs/thinlto_backend_local_name_conflict1.ll
new file mode 100644
index 0000000000..fb5306fc33
--- /dev/null
+++ b/test/CodeGen/Inputs/thinlto_backend_local_name_conflict1.ll
@@ -0,0 +1,13 @@
+; ModuleID = 'local_name_conflict_var.o'
+source_filename = "local_name_conflict_var.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@baz = internal global i32 10, align 4
+
+; Function Attrs: noinline nounwind uwtable
+define i32 @a() {
+entry:
+ %0 = load i32, i32* @baz, align 4
+ ret i32 %0
+}
diff --git a/test/CodeGen/Inputs/thinlto_backend_local_name_conflict2.ll b/test/CodeGen/Inputs/thinlto_backend_local_name_conflict2.ll
new file mode 100644
index 0000000000..bf3c262f18
--- /dev/null
+++ b/test/CodeGen/Inputs/thinlto_backend_local_name_conflict2.ll
@@ -0,0 +1,13 @@
+; ModuleID = 'local_name_conflict_var.o'
+source_filename = "local_name_conflict_var.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@baz = internal global i32 10, align 4
+
+; Function Attrs: noinline nounwind uwtable
+define i32 @b() {
+entry:
+ %0 = load i32, i32* @baz, align 4
+ ret i32 %0
+}
diff --git a/test/CodeGen/aarch64-neon-3v.c b/test/CodeGen/aarch64-neon-3v.c
index de38e95c44..0ededf940d 100644
--- a/test/CodeGen/aarch64-neon-3v.c
+++ b/test/CodeGen/aarch64-neon-3v.c
@@ -11,7 +11,7 @@ int8x8_t test_vand_s8(int8x8_t a, int8x8_t b) {
return vand_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vandq_s8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vandq_s8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <16 x i8> %a, %b
// CHECK: ret <16 x i8> [[AND_I]]
int8x16_t test_vandq_s8(int8x16_t a, int8x16_t b) {
@@ -25,7 +25,7 @@ int16x4_t test_vand_s16(int16x4_t a, int16x4_t b) {
return vand_s16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vandq_s16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vandq_s16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <8 x i16> %a, %b
// CHECK: ret <8 x i16> [[AND_I]]
int16x8_t test_vandq_s16(int16x8_t a, int16x8_t b) {
@@ -39,7 +39,7 @@ int32x2_t test_vand_s32(int32x2_t a, int32x2_t b) {
return vand_s32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vandq_s32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vandq_s32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <4 x i32> %a, %b
// CHECK: ret <4 x i32> [[AND_I]]
int32x4_t test_vandq_s32(int32x4_t a, int32x4_t b) {
@@ -53,7 +53,7 @@ int64x1_t test_vand_s64(int64x1_t a, int64x1_t b) {
return vand_s64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vandq_s64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vandq_s64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <2 x i64> %a, %b
// CHECK: ret <2 x i64> [[AND_I]]
int64x2_t test_vandq_s64(int64x2_t a, int64x2_t b) {
@@ -67,7 +67,7 @@ uint8x8_t test_vand_u8(uint8x8_t a, uint8x8_t b) {
return vand_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vandq_u8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vandq_u8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <16 x i8> %a, %b
// CHECK: ret <16 x i8> [[AND_I]]
uint8x16_t test_vandq_u8(uint8x16_t a, uint8x16_t b) {
@@ -81,7 +81,7 @@ uint16x4_t test_vand_u16(uint16x4_t a, uint16x4_t b) {
return vand_u16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vandq_u16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vandq_u16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <8 x i16> %a, %b
// CHECK: ret <8 x i16> [[AND_I]]
uint16x8_t test_vandq_u16(uint16x8_t a, uint16x8_t b) {
@@ -95,7 +95,7 @@ uint32x2_t test_vand_u32(uint32x2_t a, uint32x2_t b) {
return vand_u32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vandq_u32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vandq_u32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <4 x i32> %a, %b
// CHECK: ret <4 x i32> [[AND_I]]
uint32x4_t test_vandq_u32(uint32x4_t a, uint32x4_t b) {
@@ -109,7 +109,7 @@ uint64x1_t test_vand_u64(uint64x1_t a, uint64x1_t b) {
return vand_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vandq_u64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vandq_u64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[AND_I:%.*]] = and <2 x i64> %a, %b
// CHECK: ret <2 x i64> [[AND_I]]
uint64x2_t test_vandq_u64(uint64x2_t a, uint64x2_t b) {
@@ -123,7 +123,7 @@ int8x8_t test_vorr_s8(int8x8_t a, int8x8_t b) {
return vorr_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vorrq_s8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vorrq_s8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <16 x i8> %a, %b
// CHECK: ret <16 x i8> [[OR_I]]
int8x16_t test_vorrq_s8(int8x16_t a, int8x16_t b) {
@@ -137,7 +137,7 @@ int16x4_t test_vorr_s16(int16x4_t a, int16x4_t b) {
return vorr_s16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vorrq_s16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vorrq_s16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <8 x i16> %a, %b
// CHECK: ret <8 x i16> [[OR_I]]
int16x8_t test_vorrq_s16(int16x8_t a, int16x8_t b) {
@@ -151,7 +151,7 @@ int32x2_t test_vorr_s32(int32x2_t a, int32x2_t b) {
return vorr_s32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vorrq_s32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vorrq_s32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <4 x i32> %a, %b
// CHECK: ret <4 x i32> [[OR_I]]
int32x4_t test_vorrq_s32(int32x4_t a, int32x4_t b) {
@@ -165,7 +165,7 @@ int64x1_t test_vorr_s64(int64x1_t a, int64x1_t b) {
return vorr_s64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vorrq_s64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vorrq_s64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <2 x i64> %a, %b
// CHECK: ret <2 x i64> [[OR_I]]
int64x2_t test_vorrq_s64(int64x2_t a, int64x2_t b) {
@@ -179,7 +179,7 @@ uint8x8_t test_vorr_u8(uint8x8_t a, uint8x8_t b) {
return vorr_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vorrq_u8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vorrq_u8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <16 x i8> %a, %b
// CHECK: ret <16 x i8> [[OR_I]]
uint8x16_t test_vorrq_u8(uint8x16_t a, uint8x16_t b) {
@@ -193,7 +193,7 @@ uint16x4_t test_vorr_u16(uint16x4_t a, uint16x4_t b) {
return vorr_u16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vorrq_u16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vorrq_u16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <8 x i16> %a, %b
// CHECK: ret <8 x i16> [[OR_I]]
uint16x8_t test_vorrq_u16(uint16x8_t a, uint16x8_t b) {
@@ -207,7 +207,7 @@ uint32x2_t test_vorr_u32(uint32x2_t a, uint32x2_t b) {
return vorr_u32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vorrq_u32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vorrq_u32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <4 x i32> %a, %b
// CHECK: ret <4 x i32> [[OR_I]]
uint32x4_t test_vorrq_u32(uint32x4_t a, uint32x4_t b) {
@@ -221,7 +221,7 @@ uint64x1_t test_vorr_u64(uint64x1_t a, uint64x1_t b) {
return vorr_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vorrq_u64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vorrq_u64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[OR_I:%.*]] = or <2 x i64> %a, %b
// CHECK: ret <2 x i64> [[OR_I]]
uint64x2_t test_vorrq_u64(uint64x2_t a, uint64x2_t b) {
@@ -235,7 +235,7 @@ int8x8_t test_veor_s8(int8x8_t a, int8x8_t b) {
return veor_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_veorq_s8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_veorq_s8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <16 x i8> %a, %b
// CHECK: ret <16 x i8> [[XOR_I]]
int8x16_t test_veorq_s8(int8x16_t a, int8x16_t b) {
@@ -249,7 +249,7 @@ int16x4_t test_veor_s16(int16x4_t a, int16x4_t b) {
return veor_s16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_veorq_s16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_veorq_s16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <8 x i16> %a, %b
// CHECK: ret <8 x i16> [[XOR_I]]
int16x8_t test_veorq_s16(int16x8_t a, int16x8_t b) {
@@ -263,7 +263,7 @@ int32x2_t test_veor_s32(int32x2_t a, int32x2_t b) {
return veor_s32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_veorq_s32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_veorq_s32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <4 x i32> %a, %b
// CHECK: ret <4 x i32> [[XOR_I]]
int32x4_t test_veorq_s32(int32x4_t a, int32x4_t b) {
@@ -277,7 +277,7 @@ int64x1_t test_veor_s64(int64x1_t a, int64x1_t b) {
return veor_s64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_veorq_s64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_veorq_s64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <2 x i64> %a, %b
// CHECK: ret <2 x i64> [[XOR_I]]
int64x2_t test_veorq_s64(int64x2_t a, int64x2_t b) {
@@ -291,7 +291,7 @@ uint8x8_t test_veor_u8(uint8x8_t a, uint8x8_t b) {
return veor_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_veorq_u8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_veorq_u8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <16 x i8> %a, %b
// CHECK: ret <16 x i8> [[XOR_I]]
uint8x16_t test_veorq_u8(uint8x16_t a, uint8x16_t b) {
@@ -305,7 +305,7 @@ uint16x4_t test_veor_u16(uint16x4_t a, uint16x4_t b) {
return veor_u16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_veorq_u16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_veorq_u16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <8 x i16> %a, %b
// CHECK: ret <8 x i16> [[XOR_I]]
uint16x8_t test_veorq_u16(uint16x8_t a, uint16x8_t b) {
@@ -319,7 +319,7 @@ uint32x2_t test_veor_u32(uint32x2_t a, uint32x2_t b) {
return veor_u32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_veorq_u32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_veorq_u32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <4 x i32> %a, %b
// CHECK: ret <4 x i32> [[XOR_I]]
uint32x4_t test_veorq_u32(uint32x4_t a, uint32x4_t b) {
@@ -333,7 +333,7 @@ uint64x1_t test_veor_u64(uint64x1_t a, uint64x1_t b) {
return veor_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_veorq_u64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_veorq_u64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[XOR_I:%.*]] = xor <2 x i64> %a, %b
// CHECK: ret <2 x i64> [[XOR_I]]
uint64x2_t test_veorq_u64(uint64x2_t a, uint64x2_t b) {
@@ -348,7 +348,7 @@ int8x8_t test_vbic_s8(int8x8_t a, int8x8_t b) {
return vbic_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vbicq_s8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vbicq_s8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <16 x i8> %b, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
// CHECK: [[AND_I:%.*]] = and <16 x i8> %a, [[NEG_I]]
// CHECK: ret <16 x i8> [[AND_I]]
@@ -364,7 +364,7 @@ int16x4_t test_vbic_s16(int16x4_t a, int16x4_t b) {
return vbic_s16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vbicq_s16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vbicq_s16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <8 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
// CHECK: [[AND_I:%.*]] = and <8 x i16> %a, [[NEG_I]]
// CHECK: ret <8 x i16> [[AND_I]]
@@ -380,7 +380,7 @@ int32x2_t test_vbic_s32(int32x2_t a, int32x2_t b) {
return vbic_s32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vbicq_s32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vbicq_s32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
// CHECK: [[AND_I:%.*]] = and <4 x i32> %a, [[NEG_I]]
// CHECK: ret <4 x i32> [[AND_I]]
@@ -396,7 +396,7 @@ int64x1_t test_vbic_s64(int64x1_t a, int64x1_t b) {
return vbic_s64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vbicq_s64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vbicq_s64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <2 x i64> %b, <i64 -1, i64 -1>
// CHECK: [[AND_I:%.*]] = and <2 x i64> %a, [[NEG_I]]
// CHECK: ret <2 x i64> [[AND_I]]
@@ -412,7 +412,7 @@ uint8x8_t test_vbic_u8(uint8x8_t a, uint8x8_t b) {
return vbic_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vbicq_u8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vbicq_u8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <16 x i8> %b, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
// CHECK: [[AND_I:%.*]] = and <16 x i8> %a, [[NEG_I]]
// CHECK: ret <16 x i8> [[AND_I]]
@@ -428,7 +428,7 @@ uint16x4_t test_vbic_u16(uint16x4_t a, uint16x4_t b) {
return vbic_u16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vbicq_u16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vbicq_u16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <8 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
// CHECK: [[AND_I:%.*]] = and <8 x i16> %a, [[NEG_I]]
// CHECK: ret <8 x i16> [[AND_I]]
@@ -444,7 +444,7 @@ uint32x2_t test_vbic_u32(uint32x2_t a, uint32x2_t b) {
return vbic_u32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vbicq_u32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vbicq_u32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
// CHECK: [[AND_I:%.*]] = and <4 x i32> %a, [[NEG_I]]
// CHECK: ret <4 x i32> [[AND_I]]
@@ -460,7 +460,7 @@ uint64x1_t test_vbic_u64(uint64x1_t a, uint64x1_t b) {
return vbic_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vbicq_u64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vbicq_u64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <2 x i64> %b, <i64 -1, i64 -1>
// CHECK: [[AND_I:%.*]] = and <2 x i64> %a, [[NEG_I]]
// CHECK: ret <2 x i64> [[AND_I]]
@@ -476,7 +476,7 @@ int8x8_t test_vorn_s8(int8x8_t a, int8x8_t b) {
return vorn_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vornq_s8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vornq_s8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <16 x i8> %b, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
// CHECK: [[OR_I:%.*]] = or <16 x i8> %a, [[NEG_I]]
// CHECK: ret <16 x i8> [[OR_I]]
@@ -492,7 +492,7 @@ int16x4_t test_vorn_s16(int16x4_t a, int16x4_t b) {
return vorn_s16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vornq_s16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vornq_s16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <8 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
// CHECK: [[OR_I:%.*]] = or <8 x i16> %a, [[NEG_I]]
// CHECK: ret <8 x i16> [[OR_I]]
@@ -508,7 +508,7 @@ int32x2_t test_vorn_s32(int32x2_t a, int32x2_t b) {
return vorn_s32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vornq_s32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vornq_s32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
// CHECK: [[OR_I:%.*]] = or <4 x i32> %a, [[NEG_I]]
// CHECK: ret <4 x i32> [[OR_I]]
@@ -524,7 +524,7 @@ int64x1_t test_vorn_s64(int64x1_t a, int64x1_t b) {
return vorn_s64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vornq_s64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vornq_s64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <2 x i64> %b, <i64 -1, i64 -1>
// CHECK: [[OR_I:%.*]] = or <2 x i64> %a, [[NEG_I]]
// CHECK: ret <2 x i64> [[OR_I]]
@@ -540,7 +540,7 @@ uint8x8_t test_vorn_u8(uint8x8_t a, uint8x8_t b) {
return vorn_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vornq_u8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vornq_u8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <16 x i8> %b, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
// CHECK: [[OR_I:%.*]] = or <16 x i8> %a, [[NEG_I]]
// CHECK: ret <16 x i8> [[OR_I]]
@@ -556,7 +556,7 @@ uint16x4_t test_vorn_u16(uint16x4_t a, uint16x4_t b) {
return vorn_u16(a, b);
}
-// CHECK-LABEL: define <8 x i16> @test_vornq_u16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vornq_u16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <8 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
// CHECK: [[OR_I:%.*]] = or <8 x i16> %a, [[NEG_I]]
// CHECK: ret <8 x i16> [[OR_I]]
@@ -572,7 +572,7 @@ uint32x2_t test_vorn_u32(uint32x2_t a, uint32x2_t b) {
return vorn_u32(a, b);
}
-// CHECK-LABEL: define <4 x i32> @test_vornq_u32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vornq_u32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
// CHECK: [[OR_I:%.*]] = or <4 x i32> %a, [[NEG_I]]
// CHECK: ret <4 x i32> [[OR_I]]
@@ -588,10 +588,13 @@ uint64x1_t test_vorn_u64(uint64x1_t a, uint64x1_t b) {
return vorn_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vornq_u64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vornq_u64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[NEG_I:%.*]] = xor <2 x i64> %b, <i64 -1, i64 -1>
// CHECK: [[OR_I:%.*]] = or <2 x i64> %a, [[NEG_I]]
// CHECK: ret <2 x i64> [[OR_I]]
uint64x2_t test_vornq_u64(uint64x2_t a, uint64x2_t b) {
return vornq_u64(a, b);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-neon-across.c b/test/CodeGen/aarch64-neon-across.c
index 767825461b..4431d117a8 100644
--- a/test/CodeGen/aarch64-neon-across.c
+++ b/test/CodeGen/aarch64-neon-across.c
@@ -6,7 +6,7 @@
#include <arm_neon.h>
// CHECK-LABEL: define i16 @test_vaddlv_s8(<8 x i8> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
// CHECK: ret i16 [[TMP0]]
int16_t test_vaddlv_s8(int8x8_t a) {
@@ -14,14 +14,14 @@ int16_t test_vaddlv_s8(int8x8_t a) {
}
// CHECK-LABEL: define i32 @test_vaddlv_s16(<4 x i16> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v4i16(<4 x i16> %a) #3
// CHECK: ret i32 [[VADDLV_I]]
int32_t test_vaddlv_s16(int16x4_t a) {
return vaddlv_s16(a);
}
// CHECK-LABEL: define i16 @test_vaddlv_u8(<8 x i8> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
// CHECK: ret i16 [[TMP0]]
uint16_t test_vaddlv_u8(uint8x8_t a) {
@@ -29,58 +29,58 @@ uint16_t test_vaddlv_u8(uint8x8_t a) {
}
// CHECK-LABEL: define i32 @test_vaddlv_u16(<4 x i16> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v4i16(<4 x i16> %a) #3
// CHECK: ret i32 [[VADDLV_I]]
uint32_t test_vaddlv_u16(uint16x4_t a) {
return vaddlv_u16(a);
}
-// CHECK-LABEL: define i16 @test_vaddlvq_s8(<16 x i8> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i16 @test_vaddlvq_s8(<16 x i8> %a) #1 {
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
// CHECK: ret i16 [[TMP0]]
int16_t test_vaddlvq_s8(int8x16_t a) {
return vaddlvq_s8(a);
}
-// CHECK-LABEL: define i32 @test_vaddlvq_s16(<8 x i16> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i32 @test_vaddlvq_s16(<8 x i16> %a) #1 {
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i16(<8 x i16> %a) #3
// CHECK: ret i32 [[VADDLV_I]]
int32_t test_vaddlvq_s16(int16x8_t a) {
return vaddlvq_s16(a);
}
-// CHECK-LABEL: define i64 @test_vaddlvq_s32(<4 x i32> %a) #0 {
-// CHECK: [[VADDLVQ_S32_I:%.*]] = call i64 @llvm.aarch64.neon.saddlv.i64.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i64 @test_vaddlvq_s32(<4 x i32> %a) #1 {
+// CHECK: [[VADDLVQ_S32_I:%.*]] = call i64 @llvm.aarch64.neon.saddlv.i64.v4i32(<4 x i32> %a) #3
// CHECK: ret i64 [[VADDLVQ_S32_I]]
int64_t test_vaddlvq_s32(int32x4_t a) {
return vaddlvq_s32(a);
}
-// CHECK-LABEL: define i16 @test_vaddlvq_u8(<16 x i8> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i16 @test_vaddlvq_u8(<16 x i8> %a) #1 {
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
// CHECK: ret i16 [[TMP0]]
uint16_t test_vaddlvq_u8(uint8x16_t a) {
return vaddlvq_u8(a);
}
-// CHECK-LABEL: define i32 @test_vaddlvq_u16(<8 x i16> %a) #0 {
-// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i32 @test_vaddlvq_u16(<8 x i16> %a) #1 {
+// CHECK: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i16(<8 x i16> %a) #3
// CHECK: ret i32 [[VADDLV_I]]
uint32_t test_vaddlvq_u16(uint16x8_t a) {
return vaddlvq_u16(a);
}
-// CHECK-LABEL: define i64 @test_vaddlvq_u32(<4 x i32> %a) #0 {
-// CHECK: [[VADDLVQ_U32_I:%.*]] = call i64 @llvm.aarch64.neon.uaddlv.i64.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i64 @test_vaddlvq_u32(<4 x i32> %a) #1 {
+// CHECK: [[VADDLVQ_U32_I:%.*]] = call i64 @llvm.aarch64.neon.uaddlv.i64.v4i32(<4 x i32> %a) #3
// CHECK: ret i64 [[VADDLVQ_U32_I]]
uint64_t test_vaddlvq_u32(uint32x4_t a) {
return vaddlvq_u32(a);
}
// CHECK-LABEL: define i8 @test_vmaxv_s8(<8 x i8> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMAXV_I]] to i8
// CHECK: ret i8 [[TMP0]]
int8_t test_vmaxv_s8(int8x8_t a) {
@@ -88,7 +88,7 @@ int8_t test_vmaxv_s8(int8x8_t a) {
}
// CHECK-LABEL: define i16 @test_vmaxv_s16(<4 x i16> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v4i16(<4 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMAXV_I]] to i16
// CHECK: ret i16 [[TMP2]]
int16_t test_vmaxv_s16(int16x4_t a) {
@@ -96,7 +96,7 @@ int16_t test_vmaxv_s16(int16x4_t a) {
}
// CHECK-LABEL: define i8 @test_vmaxv_u8(<8 x i8> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMAXV_I]] to i8
// CHECK: ret i8 [[TMP0]]
uint8_t test_vmaxv_u8(uint8x8_t a) {
@@ -104,61 +104,61 @@ uint8_t test_vmaxv_u8(uint8x8_t a) {
}
// CHECK-LABEL: define i16 @test_vmaxv_u16(<4 x i16> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v4i16(<4 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMAXV_I]] to i16
// CHECK: ret i16 [[TMP2]]
uint16_t test_vmaxv_u16(uint16x4_t a) {
return vmaxv_u16(a);
}
-// CHECK-LABEL: define i8 @test_vmaxvq_s8(<16 x i8> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i8 @test_vmaxvq_s8(<16 x i8> %a) #1 {
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMAXV_I]] to i8
// CHECK: ret i8 [[TMP0]]
int8_t test_vmaxvq_s8(int8x16_t a) {
return vmaxvq_s8(a);
}
-// CHECK-LABEL: define i16 @test_vmaxvq_s16(<8 x i16> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i16 @test_vmaxvq_s16(<8 x i16> %a) #1 {
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v8i16(<8 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMAXV_I]] to i16
// CHECK: ret i16 [[TMP2]]
int16_t test_vmaxvq_s16(int16x8_t a) {
return vmaxvq_s16(a);
}
-// CHECK-LABEL: define i32 @test_vmaxvq_s32(<4 x i32> %a) #0 {
-// CHECK: [[VMAXVQ_S32_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i32 @test_vmaxvq_s32(<4 x i32> %a) #1 {
+// CHECK: [[VMAXVQ_S32_I:%.*]] = call i32 @llvm.aarch64.neon.smaxv.i32.v4i32(<4 x i32> %a) #3
// CHECK: ret i32 [[VMAXVQ_S32_I]]
int32_t test_vmaxvq_s32(int32x4_t a) {
return vmaxvq_s32(a);
}
-// CHECK-LABEL: define i8 @test_vmaxvq_u8(<16 x i8> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i8 @test_vmaxvq_u8(<16 x i8> %a) #1 {
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMAXV_I]] to i8
// CHECK: ret i8 [[TMP0]]
uint8_t test_vmaxvq_u8(uint8x16_t a) {
return vmaxvq_u8(a);
}
-// CHECK-LABEL: define i16 @test_vmaxvq_u16(<8 x i16> %a) #0 {
-// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i16 @test_vmaxvq_u16(<8 x i16> %a) #1 {
+// CHECK: [[VMAXV_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v8i16(<8 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMAXV_I]] to i16
// CHECK: ret i16 [[TMP2]]
uint16_t test_vmaxvq_u16(uint16x8_t a) {
return vmaxvq_u16(a);
}
-// CHECK-LABEL: define i32 @test_vmaxvq_u32(<4 x i32> %a) #0 {
-// CHECK: [[VMAXVQ_U32_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i32 @test_vmaxvq_u32(<4 x i32> %a) #1 {
+// CHECK: [[VMAXVQ_U32_I:%.*]] = call i32 @llvm.aarch64.neon.umaxv.i32.v4i32(<4 x i32> %a) #3
// CHECK: ret i32 [[VMAXVQ_U32_I]]
uint32_t test_vmaxvq_u32(uint32x4_t a) {
return vmaxvq_u32(a);
}
// CHECK-LABEL: define i8 @test_vminv_s8(<8 x i8> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMINV_I]] to i8
// CHECK: ret i8 [[TMP0]]
int8_t test_vminv_s8(int8x8_t a) {
@@ -166,7 +166,7 @@ int8_t test_vminv_s8(int8x8_t a) {
}
// CHECK-LABEL: define i16 @test_vminv_s16(<4 x i16> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v4i16(<4 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMINV_I]] to i16
// CHECK: ret i16 [[TMP2]]
int16_t test_vminv_s16(int16x4_t a) {
@@ -174,7 +174,7 @@ int16_t test_vminv_s16(int16x4_t a) {
}
// CHECK-LABEL: define i8 @test_vminv_u8(<8 x i8> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMINV_I]] to i8
// CHECK: ret i8 [[TMP0]]
uint8_t test_vminv_u8(uint8x8_t a) {
@@ -182,61 +182,61 @@ uint8_t test_vminv_u8(uint8x8_t a) {
}
// CHECK-LABEL: define i16 @test_vminv_u16(<4 x i16> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v4i16(<4 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMINV_I]] to i16
// CHECK: ret i16 [[TMP2]]
uint16_t test_vminv_u16(uint16x4_t a) {
return vminv_u16(a);
}
-// CHECK-LABEL: define i8 @test_vminvq_s8(<16 x i8> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i8 @test_vminvq_s8(<16 x i8> %a) #1 {
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMINV_I]] to i8
// CHECK: ret i8 [[TMP0]]
int8_t test_vminvq_s8(int8x16_t a) {
return vminvq_s8(a);
}
-// CHECK-LABEL: define i16 @test_vminvq_s16(<8 x i16> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i16 @test_vminvq_s16(<8 x i16> %a) #1 {
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v8i16(<8 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMINV_I]] to i16
// CHECK: ret i16 [[TMP2]]
int16_t test_vminvq_s16(int16x8_t a) {
return vminvq_s16(a);
}
-// CHECK-LABEL: define i32 @test_vminvq_s32(<4 x i32> %a) #0 {
-// CHECK: [[VMINVQ_S32_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i32 @test_vminvq_s32(<4 x i32> %a) #1 {
+// CHECK: [[VMINVQ_S32_I:%.*]] = call i32 @llvm.aarch64.neon.sminv.i32.v4i32(<4 x i32> %a) #3
// CHECK: ret i32 [[VMINVQ_S32_I]]
int32_t test_vminvq_s32(int32x4_t a) {
return vminvq_s32(a);
}
-// CHECK-LABEL: define i8 @test_vminvq_u8(<16 x i8> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i8 @test_vminvq_u8(<16 x i8> %a) #1 {
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VMINV_I]] to i8
// CHECK: ret i8 [[TMP0]]
uint8_t test_vminvq_u8(uint8x16_t a) {
return vminvq_u8(a);
}
-// CHECK-LABEL: define i16 @test_vminvq_u16(<8 x i16> %a) #0 {
-// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i16 @test_vminvq_u16(<8 x i16> %a) #1 {
+// CHECK: [[VMINV_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v8i16(<8 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VMINV_I]] to i16
// CHECK: ret i16 [[TMP2]]
uint16_t test_vminvq_u16(uint16x8_t a) {
return vminvq_u16(a);
}
-// CHECK-LABEL: define i32 @test_vminvq_u32(<4 x i32> %a) #0 {
-// CHECK: [[VMINVQ_U32_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i32 @test_vminvq_u32(<4 x i32> %a) #1 {
+// CHECK: [[VMINVQ_U32_I:%.*]] = call i32 @llvm.aarch64.neon.uminv.i32.v4i32(<4 x i32> %a) #3
// CHECK: ret i32 [[VMINVQ_U32_I]]
uint32_t test_vminvq_u32(uint32x4_t a) {
return vminvq_u32(a);
}
// CHECK-LABEL: define i8 @test_vaddv_s8(<8 x i8> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDV_I]] to i8
// CHECK: ret i8 [[TMP0]]
int8_t test_vaddv_s8(int8x8_t a) {
@@ -244,7 +244,7 @@ int8_t test_vaddv_s8(int8x8_t a) {
}
// CHECK-LABEL: define i16 @test_vaddv_s16(<4 x i16> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v4i16(<4 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VADDV_I]] to i16
// CHECK: ret i16 [[TMP2]]
int16_t test_vaddv_s16(int16x4_t a) {
@@ -252,7 +252,7 @@ int16_t test_vaddv_s16(int16x4_t a) {
}
// CHECK-LABEL: define i8 @test_vaddv_u8(<8 x i8> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v8i8(<8 x i8> %a) #2
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v8i8(<8 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDV_I]] to i8
// CHECK: ret i8 [[TMP0]]
uint8_t test_vaddv_u8(uint8x8_t a) {
@@ -260,83 +260,86 @@ uint8_t test_vaddv_u8(uint8x8_t a) {
}
// CHECK-LABEL: define i16 @test_vaddv_u16(<4 x i16> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v4i16(<4 x i16> %a) #2
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v4i16(<4 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VADDV_I]] to i16
// CHECK: ret i16 [[TMP2]]
uint16_t test_vaddv_u16(uint16x4_t a) {
return vaddv_u16(a);
}
-// CHECK-LABEL: define i8 @test_vaddvq_s8(<16 x i8> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i8 @test_vaddvq_s8(<16 x i8> %a) #1 {
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDV_I]] to i8
// CHECK: ret i8 [[TMP0]]
int8_t test_vaddvq_s8(int8x16_t a) {
return vaddvq_s8(a);
}
-// CHECK-LABEL: define i16 @test_vaddvq_s16(<8 x i16> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i16 @test_vaddvq_s16(<8 x i16> %a) #1 {
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v8i16(<8 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VADDV_I]] to i16
// CHECK: ret i16 [[TMP2]]
int16_t test_vaddvq_s16(int16x8_t a) {
return vaddvq_s16(a);
}
-// CHECK-LABEL: define i32 @test_vaddvq_s32(<4 x i32> %a) #0 {
-// CHECK: [[VADDVQ_S32_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i32 @test_vaddvq_s32(<4 x i32> %a) #1 {
+// CHECK: [[VADDVQ_S32_I:%.*]] = call i32 @llvm.aarch64.neon.saddv.i32.v4i32(<4 x i32> %a) #3
// CHECK: ret i32 [[VADDVQ_S32_I]]
int32_t test_vaddvq_s32(int32x4_t a) {
return vaddvq_s32(a);
}
-// CHECK-LABEL: define i8 @test_vaddvq_u8(<16 x i8> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8> %a) #2
+// CHECK-LABEL: define i8 @test_vaddvq_u8(<16 x i8> %a) #1 {
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8> %a) #3
// CHECK: [[TMP0:%.*]] = trunc i32 [[VADDV_I]] to i8
// CHECK: ret i8 [[TMP0]]
uint8_t test_vaddvq_u8(uint8x16_t a) {
return vaddvq_u8(a);
}
-// CHECK-LABEL: define i16 @test_vaddvq_u16(<8 x i16> %a) #0 {
-// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v8i16(<8 x i16> %a) #2
+// CHECK-LABEL: define i16 @test_vaddvq_u16(<8 x i16> %a) #1 {
+// CHECK: [[VADDV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v8i16(<8 x i16> %a) #3
// CHECK: [[TMP2:%.*]] = trunc i32 [[VADDV_I]] to i16
// CHECK: ret i16 [[TMP2]]
uint16_t test_vaddvq_u16(uint16x8_t a) {
return vaddvq_u16(a);
}
-// CHECK-LABEL: define i32 @test_vaddvq_u32(<4 x i32> %a) #0 {
-// CHECK: [[VADDVQ_U32_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32> %a) #2
+// CHECK-LABEL: define i32 @test_vaddvq_u32(<4 x i32> %a) #1 {
+// CHECK: [[VADDVQ_U32_I:%.*]] = call i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32> %a) #3
// CHECK: ret i32 [[VADDVQ_U32_I]]
uint32_t test_vaddvq_u32(uint32x4_t a) {
return vaddvq_u32(a);
}
-// CHECK-LABEL: define float @test_vmaxvq_f32(<4 x float> %a) #0 {
-// CHECK: [[VMAXVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxv.f32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define float @test_vmaxvq_f32(<4 x float> %a) #1 {
+// CHECK: [[VMAXVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxv.f32.v4f32(<4 x float> %a) #3
// CHECK: ret float [[VMAXVQ_F32_I]]
float32_t test_vmaxvq_f32(float32x4_t a) {
return vmaxvq_f32(a);
}
-// CHECK-LABEL: define float @test_vminvq_f32(<4 x float> %a) #0 {
-// CHECK: [[VMINVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fminv.f32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define float @test_vminvq_f32(<4 x float> %a) #1 {
+// CHECK: [[VMINVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fminv.f32.v4f32(<4 x float> %a) #3
// CHECK: ret float [[VMINVQ_F32_I]]
float32_t test_vminvq_f32(float32x4_t a) {
return vminvq_f32(a);
}
-// CHECK-LABEL: define float @test_vmaxnmvq_f32(<4 x float> %a) #0 {
-// CHECK: [[VMAXNMVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxnmv.f32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define float @test_vmaxnmvq_f32(<4 x float> %a) #1 {
+// CHECK: [[VMAXNMVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxnmv.f32.v4f32(<4 x float> %a) #3
// CHECK: ret float [[VMAXNMVQ_F32_I]]
float32_t test_vmaxnmvq_f32(float32x4_t a) {
return vmaxnmvq_f32(a);
}
-// CHECK-LABEL: define float @test_vminnmvq_f32(<4 x float> %a) #0 {
-// CHECK: [[VMINNMVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fminnmv.f32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define float @test_vminnmvq_f32(<4 x float> %a) #1 {
+// CHECK: [[VMINNMVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fminnmv.f32.v4f32(<4 x float> %a) #3
// CHECK: ret float [[VMINNMVQ_F32_I]]
float32_t test_vminnmvq_f32(float32x4_t a) {
return vminnmvq_f32(a);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-neon-extract.c b/test/CodeGen/aarch64-neon-extract.c
index 6b62d9f1cf..cd40b31139 100644
--- a/test/CodeGen/aarch64-neon-extract.c
+++ b/test/CodeGen/aarch64-neon-extract.c
@@ -46,14 +46,14 @@ int64x1_t test_vext_s64(int64x1_t a, int64x1_t b) {
return vext_s64(a, b, 0);
}
-// CHECK-LABEL: define <16 x i8> @test_vextq_s8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vextq_s8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[VEXT:%.*]] = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17>
// CHECK: ret <16 x i8> [[VEXT]]
int8x16_t test_vextq_s8(int8x16_t a, int8x16_t b) {
return vextq_s8(a, b, 2);
}
-// CHECK-LABEL: define <8 x i16> @test_vextq_s16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vextq_s16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
@@ -64,7 +64,7 @@ int16x8_t test_vextq_s16(int16x8_t a, int16x8_t b) {
return vextq_s16(a, b, 3);
}
-// CHECK-LABEL: define <4 x i32> @test_vextq_s32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vextq_s32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
@@ -75,7 +75,7 @@ int32x4_t test_vextq_s32(int32x4_t a, int32x4_t b) {
return vextq_s32(a, b, 1);
}
-// CHECK-LABEL: define <2 x i64> @test_vextq_s64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vextq_s64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
@@ -126,14 +126,14 @@ uint64x1_t test_vext_u64(uint64x1_t a, uint64x1_t b) {
return vext_u64(a, b, 0);
}
-// CHECK-LABEL: define <16 x i8> @test_vextq_u8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vextq_u8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[VEXT:%.*]] = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17>
// CHECK: ret <16 x i8> [[VEXT]]
uint8x16_t test_vextq_u8(uint8x16_t a, uint8x16_t b) {
return vextq_u8(a, b, 2);
}
-// CHECK-LABEL: define <8 x i16> @test_vextq_u16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vextq_u16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
@@ -144,7 +144,7 @@ uint16x8_t test_vextq_u16(uint16x8_t a, uint16x8_t b) {
return vextq_u16(a, b, 3);
}
-// CHECK-LABEL: define <4 x i32> @test_vextq_u32(<4 x i32> %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vextq_u32(<4 x i32> %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
@@ -155,7 +155,7 @@ uint32x4_t test_vextq_u32(uint32x4_t a, uint32x4_t b) {
return vextq_u32(a, b, 1);
}
-// CHECK-LABEL: define <2 x i64> @test_vextq_u64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vextq_u64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
@@ -188,7 +188,7 @@ float64x1_t test_vext_f64(float64x1_t a, float64x1_t b) {
return vext_f64(a, b, 0);
}
-// CHECK-LABEL: define <4 x float> @test_vextq_f32(<4 x float> %a, <4 x float> %b) #0 {
+// CHECK-LABEL: define <4 x float> @test_vextq_f32(<4 x float> %a, <4 x float> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float>
@@ -199,7 +199,7 @@ float32x4_t test_vextq_f32(float32x4_t a, float32x4_t b) {
return vextq_f32(a, b, 1);
}
-// CHECK-LABEL: define <2 x double> @test_vextq_f64(<2 x double> %a, <2 x double> %b) #0 {
+// CHECK-LABEL: define <2 x double> @test_vextq_f64(<2 x double> %a, <2 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x double> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x double>
@@ -228,14 +228,14 @@ poly16x4_t test_vext_p16(poly16x4_t a, poly16x4_t b) {
return vext_p16(a, b, 3);
}
-// CHECK-LABEL: define <16 x i8> @test_vextq_p8(<16 x i8> %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vextq_p8(<16 x i8> %a, <16 x i8> %b) #1 {
// CHECK: [[VEXT:%.*]] = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17>
// CHECK: ret <16 x i8> [[VEXT]]
poly8x16_t test_vextq_p8(poly8x16_t a, poly8x16_t b) {
return vextq_p8(a, b, 2);
}
-// CHECK-LABEL: define <8 x i16> @test_vextq_p16(<8 x i16> %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vextq_p16(<8 x i16> %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
diff --git a/test/CodeGen/aarch64-neon-fma.c b/test/CodeGen/aarch64-neon-fma.c
index 3a84834e11..564bd37e78 100644
--- a/test/CodeGen/aarch64-neon-fma.c
+++ b/test/CodeGen/aarch64-neon-fma.c
@@ -14,7 +14,7 @@ float32x2_t test_vmla_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
return vmla_n_f32(a, b, c);
}
-// CHECK-LABEL: define <4 x float> @test_vmlaq_n_f32(<4 x float> %a, <4 x float> %b, float %c) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlaq_n_f32(<4 x float> %a, <4 x float> %b, float %c) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %c, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %c, i32 1
// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %c, i32 2
@@ -26,7 +26,7 @@ float32x4_t test_vmlaq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
return vmlaq_n_f32(a, b, c);
}
-// CHECK-LABEL: define <2 x double> @test_vmlaq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #0 {
+// CHECK-LABEL: define <2 x double> @test_vmlaq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double %c, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double %c, i32 1
// CHECK: [[MUL_I:%.*]] = fmul <2 x double> %b, [[VECINIT1_I]]
@@ -36,7 +36,7 @@ float64x2_t test_vmlaq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
return vmlaq_n_f64(a, b, c);
}
-// CHECK-LABEL: define <4 x float> @test_vmlsq_n_f32(<4 x float> %a, <4 x float> %b, float %c) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlsq_n_f32(<4 x float> %a, <4 x float> %b, float %c) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %c, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %c, i32 1
// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %c, i32 2
@@ -58,7 +58,7 @@ float32x2_t test_vmls_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
return vmls_n_f32(a, b, c);
}
-// CHECK-LABEL: define <2 x double> @test_vmlsq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #0 {
+// CHECK-LABEL: define <2 x double> @test_vmlsq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double %c, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double %c, i32 1
// CHECK: [[MUL_I:%.*]] = fmul <2 x double> %b, [[VECINIT1_I]]
@@ -77,7 +77,7 @@ float32x2_t test_vmla_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) {
return vmla_lane_f32(a, b, v, 0);
}
-// CHECK-LABEL: define <4 x float> @test_vmlaq_lane_f32_0(<4 x float> %a, <4 x float> %b, <2 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlaq_lane_f32_0(<4 x float> %a, <4 x float> %b, <2 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <2 x float> %v, <2 x float> %v, <4 x i32> zeroinitializer
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[ADD:%.*]] = fadd <4 x float> %a, [[MUL]]
@@ -86,7 +86,7 @@ float32x4_t test_vmlaq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) {
return vmlaq_lane_f32(a, b, v, 0);
}
-// CHECK-LABEL: define <2 x float> @test_vmla_laneq_f32_0(<2 x float> %a, <2 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <2 x float> @test_vmla_laneq_f32_0(<2 x float> %a, <2 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <2 x i32> zeroinitializer
// CHECK: [[MUL:%.*]] = fmul <2 x float> %b, [[SHUFFLE]]
// CHECK: [[ADD:%.*]] = fadd <2 x float> %a, [[MUL]]
@@ -95,7 +95,7 @@ float32x2_t test_vmla_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) {
return vmla_laneq_f32(a, b, v, 0);
}
-// CHECK-LABEL: define <4 x float> @test_vmlaq_laneq_f32_0(<4 x float> %a, <4 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlaq_laneq_f32_0(<4 x float> %a, <4 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <4 x i32> zeroinitializer
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[ADD:%.*]] = fadd <4 x float> %a, [[MUL]]
@@ -113,7 +113,7 @@ float32x2_t test_vmls_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) {
return vmls_lane_f32(a, b, v, 0);
}
-// CHECK-LABEL: define <4 x float> @test_vmlsq_lane_f32_0(<4 x float> %a, <4 x float> %b, <2 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlsq_lane_f32_0(<4 x float> %a, <4 x float> %b, <2 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <2 x float> %v, <2 x float> %v, <4 x i32> zeroinitializer
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[SUB:%.*]] = fsub <4 x float> %a, [[MUL]]
@@ -122,7 +122,7 @@ float32x4_t test_vmlsq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) {
return vmlsq_lane_f32(a, b, v, 0);
}
-// CHECK-LABEL: define <2 x float> @test_vmls_laneq_f32_0(<2 x float> %a, <2 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <2 x float> @test_vmls_laneq_f32_0(<2 x float> %a, <2 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <2 x i32> zeroinitializer
// CHECK: [[MUL:%.*]] = fmul <2 x float> %b, [[SHUFFLE]]
// CHECK: [[SUB:%.*]] = fsub <2 x float> %a, [[MUL]]
@@ -131,7 +131,7 @@ float32x2_t test_vmls_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) {
return vmls_laneq_f32(a, b, v, 0);
}
-// CHECK-LABEL: define <4 x float> @test_vmlsq_laneq_f32_0(<4 x float> %a, <4 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlsq_laneq_f32_0(<4 x float> %a, <4 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <4 x i32> zeroinitializer
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[SUB:%.*]] = fsub <4 x float> %a, [[MUL]]
@@ -149,7 +149,7 @@ float32x2_t test_vmla_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
return vmla_lane_f32(a, b, v, 1);
}
-// CHECK-LABEL: define <4 x float> @test_vmlaq_lane_f32(<4 x float> %a, <4 x float> %b, <2 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlaq_lane_f32(<4 x float> %a, <4 x float> %b, <2 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <2 x float> %v, <2 x float> %v, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[ADD:%.*]] = fadd <4 x float> %a, [[MUL]]
@@ -158,7 +158,7 @@ float32x4_t test_vmlaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) {
return vmlaq_lane_f32(a, b, v, 1);
}
-// CHECK-LABEL: define <2 x float> @test_vmla_laneq_f32(<2 x float> %a, <2 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <2 x float> @test_vmla_laneq_f32(<2 x float> %a, <2 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <2 x i32> <i32 3, i32 3>
// CHECK: [[MUL:%.*]] = fmul <2 x float> %b, [[SHUFFLE]]
// CHECK: [[ADD:%.*]] = fadd <2 x float> %a, [[MUL]]
@@ -167,7 +167,7 @@ float32x2_t test_vmla_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) {
return vmla_laneq_f32(a, b, v, 3);
}
-// CHECK-LABEL: define <4 x float> @test_vmlaq_laneq_f32(<4 x float> %a, <4 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlaq_laneq_f32(<4 x float> %a, <4 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[ADD:%.*]] = fadd <4 x float> %a, [[MUL]]
@@ -185,7 +185,7 @@ float32x2_t test_vmls_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
return vmls_lane_f32(a, b, v, 1);
}
-// CHECK-LABEL: define <4 x float> @test_vmlsq_lane_f32(<4 x float> %a, <4 x float> %b, <2 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlsq_lane_f32(<4 x float> %a, <4 x float> %b, <2 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <2 x float> %v, <2 x float> %v, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[SUB:%.*]] = fsub <4 x float> %a, [[MUL]]
@@ -193,7 +193,7 @@ float32x2_t test_vmls_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
float32x4_t test_vmlsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) {
return vmlsq_lane_f32(a, b, v, 1);
}
-// CHECK-LABEL: define <2 x float> @test_vmls_laneq_f32(<2 x float> %a, <2 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <2 x float> @test_vmls_laneq_f32(<2 x float> %a, <2 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <2 x i32> <i32 3, i32 3>
// CHECK: [[MUL:%.*]] = fmul <2 x float> %b, [[SHUFFLE]]
// CHECK: [[SUB:%.*]] = fsub <2 x float> %a, [[MUL]]
@@ -202,7 +202,7 @@ float32x2_t test_vmls_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) {
return vmls_laneq_f32(a, b, v, 3);
}
-// CHECK-LABEL: define <4 x float> @test_vmlsq_laneq_f32(<4 x float> %a, <4 x float> %b, <4 x float> %v) #0 {
+// CHECK-LABEL: define <4 x float> @test_vmlsq_laneq_f32(<4 x float> %a, <4 x float> %b, <4 x float> %v) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x float> %v, <4 x float> %v, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
// CHECK: [[MUL:%.*]] = fmul <4 x float> %b, [[SHUFFLE]]
// CHECK: [[SUB:%.*]] = fsub <4 x float> %a, [[MUL]]
@@ -211,7 +211,7 @@ float32x4_t test_vmlsq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) {
return vmlsq_laneq_f32(a, b, v, 3);
}
-// CHECK-LABEL: define <2 x double> @test_vfmaq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #0 {
+// CHECK-LABEL: define <2 x double> @test_vfmaq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double %c, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double %c, i32 1
// CHECK: [[TMP6:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> [[VECINIT1_I]], <2 x double> %a)
@@ -220,12 +220,15 @@ float64x2_t test_vfmaq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
return vfmaq_n_f64(a, b, c);
}
-// CHECK-LABEL: define <2 x double> @test_vfmsq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #0 {
+// CHECK-LABEL: define <2 x double> @test_vfmsq_n_f64(<2 x double> %a, <2 x double> %b, double %c) #1 {
// CHECK: [[SUB_I:%.*]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %b
// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double %c, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double %c, i32 1
-// CHECK: [[TMP6:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[SUB_I]], <2 x double> [[VECINIT1_I]], <2 x double> %a) #2
+// CHECK: [[TMP6:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[SUB_I]], <2 x double> [[VECINIT1_I]], <2 x double> %a) #3
// CHECK: ret <2 x double> [[TMP6]]
float64x2_t test_vfmsq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
return vfmsq_n_f64(a, b, c);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-neon-fp16fml.c b/test/CodeGen/aarch64-neon-fp16fml.c
new file mode 100644
index 0000000000..ad3dd9c226
--- /dev/null
+++ b/test/CodeGen/aarch64-neon-fp16fml.c
@@ -0,0 +1,196 @@
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +v8.2a -target-feature +neon -target-feature +fp16fml \
+// RUN: -fallow-half-arguments-and-returns -disable-O0-optnone -emit-llvm -o - %s | opt -S -instcombine | FileCheck %s
+
+// REQUIRES: aarch64-registered-target
+
+// Test AArch64 Armv8.2-A FP16 Fused Multiply-Add Long intrinsics
+
+#include <arm_neon.h>
+
+// Vector form
+
+float32x2_t test_vfmlal_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlal_low_u32(a, b, c);
+}
+
+float32x2_t test_vfmlsl_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlsl_low_u32(a, b, c);
+}
+
+float32x2_t test_vfmlal_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlal_high_u32(a, b, c);
+}
+
+float32x2_t test_vfmlsl_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlsl_high_u32(a, b, c);
+}
+
+float32x4_t test_vfmlalq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlalq_low_u32(a, b, c);
+}
+
+float32x4_t test_vfmlslq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlslq_low_u32(a, b, c);
+}
+
+float32x4_t test_vfmlalq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlalq_high_u32(a, b, c);
+}
+
+float32x4_t test_vfmlslq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlslq_high_u32(a, b, c);
+}
+
+// Indexed form
+
+float32x2_t test_vfmlal_lane_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_lane_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> zeroinitializer
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlal_lane_low_u32(a, b, c, 0);
+}
+
+float32x2_t test_vfmlal_lane_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_lane_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlal_lane_high_u32(a, b, c, 1);
+}
+
+float32x4_t test_vfmlalq_lane_low_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_lane_low_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlalq_lane_low_u32(a, b, c, 2);
+}
+
+float32x4_t test_vfmlalq_lane_high_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_lane_high_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlalq_lane_high_u32(a, b, c, 3);
+}
+
+float32x2_t test_vfmlal_laneq_low_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_laneq_low_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 4, i32 4, i32 4, i32 4>
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlal_laneq_low_u32(a, b, c, 4);
+}
+
+float32x2_t test_vfmlal_laneq_high_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_laneq_high_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlal_laneq_high_u32(a, b, c, 5);
+}
+
+float32x4_t test_vfmlalq_laneq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_laneq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlalq_laneq_low_u32(a, b, c, 6);
+}
+
+float32x4_t test_vfmlalq_laneq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_laneq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlalq_laneq_high_u32(a, b, c, 7);
+}
+
+float32x2_t test_vfmlsl_lane_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_lane_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> zeroinitializer
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlsl_lane_low_u32(a, b, c, 0);
+}
+
+float32x2_t test_vfmlsl_lane_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_lane_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlsl_lane_high_u32(a, b, c, 1);
+}
+
+float32x4_t test_vfmlslq_lane_low_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_lane_low_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlslq_lane_low_u32(a, b, c, 2);
+}
+
+float32x4_t test_vfmlslq_lane_high_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_lane_high_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlslq_lane_high_u32(a, b, c, 3);
+}
+
+float32x2_t test_vfmlsl_laneq_low_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_laneq_low_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 4, i32 4, i32 4, i32 4>
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlsl_laneq_low_u32(a, b, c, 4);
+}
+
+float32x2_t test_vfmlsl_laneq_high_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_laneq_high_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
+// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
+// CHECK: ret <2 x float> [[RESULT]]
+ return vfmlsl_laneq_high_u32(a, b, c, 5);
+}
+
+float32x4_t test_vfmlslq_laneq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_laneq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlslq_laneq_low_u32(a, b, c, 6);
+}
+
+float32x4_t test_vfmlslq_laneq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_laneq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>
+// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
+// CHECK: ret <4 x float> [[RESULT]]
+ return vfmlslq_laneq_high_u32(a, b, c, 7);
+}
diff --git a/test/CodeGen/aarch64-neon-ldst-one.c b/test/CodeGen/aarch64-neon-ldst-one.c
index 592b2ceffa..0d20982408 100644
--- a/test/CodeGen/aarch64-neon-ldst-one.c
+++ b/test/CodeGen/aarch64-neon-ldst-one.c
@@ -152,7 +152,7 @@ poly64x2_t test_vld1q_dup_p64(poly64_t *a) {
return vld1q_dup_p64(a);
}
-// CHECK-LABEL: define <8 x i8> @test_vld1_dup_u8(i8* %a) #0 {
+// CHECK-LABEL: define <8 x i8> @test_vld1_dup_u8(i8* %a) #1 {
// CHECK: [[TMP0:%.*]] = load i8, i8* %a
// CHECK: [[TMP1:%.*]] = insertelement <8 x i8> undef, i8 [[TMP0]], i32 0
// CHECK: [[LANE:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP1]], <8 x i32> zeroinitializer
@@ -161,7 +161,7 @@ uint8x8_t test_vld1_dup_u8(uint8_t *a) {
return vld1_dup_u8(a);
}
-// CHECK-LABEL: define <4 x i16> @test_vld1_dup_u16(i16* %a) #0 {
+// CHECK-LABEL: define <4 x i16> @test_vld1_dup_u16(i16* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i16*
// CHECK: [[TMP2:%.*]] = load i16, i16* [[TMP1]]
@@ -172,7 +172,7 @@ uint16x4_t test_vld1_dup_u16(uint16_t *a) {
return vld1_dup_u16(a);
}
-// CHECK-LABEL: define <2 x i32> @test_vld1_dup_u32(i32* %a) #0 {
+// CHECK-LABEL: define <2 x i32> @test_vld1_dup_u32(i32* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i32* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
// CHECK: [[TMP2:%.*]] = load i32, i32* [[TMP1]]
@@ -183,7 +183,7 @@ uint32x2_t test_vld1_dup_u32(uint32_t *a) {
return vld1_dup_u32(a);
}
-// CHECK-LABEL: define <1 x i64> @test_vld1_dup_u64(i64* %a) #0 {
+// CHECK-LABEL: define <1 x i64> @test_vld1_dup_u64(i64* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i64*
// CHECK: [[TMP2:%.*]] = load i64, i64* [[TMP1]]
@@ -194,7 +194,7 @@ uint64x1_t test_vld1_dup_u64(uint64_t *a) {
return vld1_dup_u64(a);
}
-// CHECK-LABEL: define <8 x i8> @test_vld1_dup_s8(i8* %a) #0 {
+// CHECK-LABEL: define <8 x i8> @test_vld1_dup_s8(i8* %a) #1 {
// CHECK: [[TMP0:%.*]] = load i8, i8* %a
// CHECK: [[TMP1:%.*]] = insertelement <8 x i8> undef, i8 [[TMP0]], i32 0
// CHECK: [[LANE:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP1]], <8 x i32> zeroinitializer
@@ -203,7 +203,7 @@ int8x8_t test_vld1_dup_s8(int8_t *a) {
return vld1_dup_s8(a);
}
-// CHECK-LABEL: define <4 x i16> @test_vld1_dup_s16(i16* %a) #0 {
+// CHECK-LABEL: define <4 x i16> @test_vld1_dup_s16(i16* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i16*
// CHECK: [[TMP2:%.*]] = load i16, i16* [[TMP1]]
@@ -214,7 +214,7 @@ int16x4_t test_vld1_dup_s16(int16_t *a) {
return vld1_dup_s16(a);
}
-// CHECK-LABEL: define <2 x i32> @test_vld1_dup_s32(i32* %a) #0 {
+// CHECK-LABEL: define <2 x i32> @test_vld1_dup_s32(i32* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i32* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
// CHECK: [[TMP2:%.*]] = load i32, i32* [[TMP1]]
@@ -225,7 +225,7 @@ int32x2_t test_vld1_dup_s32(int32_t *a) {
return vld1_dup_s32(a);
}
-// CHECK-LABEL: define <1 x i64> @test_vld1_dup_s64(i64* %a) #0 {
+// CHECK-LABEL: define <1 x i64> @test_vld1_dup_s64(i64* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i64*
// CHECK: [[TMP2:%.*]] = load i64, i64* [[TMP1]]
@@ -236,7 +236,7 @@ int64x1_t test_vld1_dup_s64(int64_t *a) {
return vld1_dup_s64(a);
}
-// CHECK-LABEL: define <4 x half> @test_vld1_dup_f16(half* %a) #0 {
+// CHECK-LABEL: define <4 x half> @test_vld1_dup_f16(half* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast half* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to half*
// CHECK: [[TMP2:%.*]] = load half, half* [[TMP1]]
@@ -247,7 +247,7 @@ float16x4_t test_vld1_dup_f16(float16_t *a) {
return vld1_dup_f16(a);
}
-// CHECK-LABEL: define <2 x float> @test_vld1_dup_f32(float* %a) #0 {
+// CHECK-LABEL: define <2 x float> @test_vld1_dup_f32(float* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast float* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to float*
// CHECK: [[TMP2:%.*]] = load float, float* [[TMP1]]
@@ -258,7 +258,7 @@ float32x2_t test_vld1_dup_f32(float32_t *a) {
return vld1_dup_f32(a);
}
-// CHECK-LABEL: define <1 x double> @test_vld1_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define <1 x double> @test_vld1_dup_f64(double* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast double* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to double*
// CHECK: [[TMP2:%.*]] = load double, double* [[TMP1]]
@@ -269,7 +269,7 @@ float64x1_t test_vld1_dup_f64(float64_t *a) {
return vld1_dup_f64(a);
}
-// CHECK-LABEL: define <8 x i8> @test_vld1_dup_p8(i8* %a) #0 {
+// CHECK-LABEL: define <8 x i8> @test_vld1_dup_p8(i8* %a) #1 {
// CHECK: [[TMP0:%.*]] = load i8, i8* %a
// CHECK: [[TMP1:%.*]] = insertelement <8 x i8> undef, i8 [[TMP0]], i32 0
// CHECK: [[LANE:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP1]], <8 x i32> zeroinitializer
@@ -278,7 +278,7 @@ poly8x8_t test_vld1_dup_p8(poly8_t *a) {
return vld1_dup_p8(a);
}
-// CHECK-LABEL: define <4 x i16> @test_vld1_dup_p16(i16* %a) #0 {
+// CHECK-LABEL: define <4 x i16> @test_vld1_dup_p16(i16* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i16*
// CHECK: [[TMP2:%.*]] = load i16, i16* [[TMP1]]
@@ -289,7 +289,7 @@ poly16x4_t test_vld1_dup_p16(poly16_t *a) {
return vld1_dup_p16(a);
}
-// CHECK-LABEL: define <1 x i64> @test_vld1_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define <1 x i64> @test_vld1_dup_p64(i64* %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i64*
// CHECK: [[TMP2:%.*]] = load i64, i64* [[TMP1]]
@@ -300,7 +300,7 @@ poly64x1_t test_vld1_dup_p64(poly64_t *a) {
return vld1_dup_p64(a);
}
-// CHECK-LABEL: define %struct.uint64x2x2_t @test_vld2q_dup_u64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.uint64x2x2_t @test_vld2q_dup_u64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x2x2_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.uint64x2x2_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.uint64x2x2_t* [[__RET]] to i8*
@@ -318,7 +318,7 @@ uint64x2x2_t test_vld2q_dup_u64(uint64_t *a) {
return vld2q_dup_u64(a);
}
-// CHECK-LABEL: define %struct.int64x2x2_t @test_vld2q_dup_s64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.int64x2x2_t @test_vld2q_dup_s64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x2x2_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.int64x2x2_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.int64x2x2_t* [[__RET]] to i8*
@@ -336,7 +336,7 @@ int64x2x2_t test_vld2q_dup_s64(int64_t *a) {
return vld2q_dup_s64(a);
}
-// CHECK-LABEL: define %struct.float64x2x2_t @test_vld2q_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define %struct.float64x2x2_t @test_vld2q_dup_f64(double* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x2x2_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.float64x2x2_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.float64x2x2_t* [[__RET]] to i8*
@@ -354,7 +354,7 @@ float64x2x2_t test_vld2q_dup_f64(float64_t *a) {
return vld2q_dup_f64(a);
}
-// CHECK-LABEL: define %struct.poly64x2x2_t @test_vld2q_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.poly64x2x2_t @test_vld2q_dup_p64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x2x2_t* [[__RET]] to i8*
@@ -372,7 +372,7 @@ poly64x2x2_t test_vld2q_dup_p64(poly64_t *a) {
return vld2q_dup_p64(a);
}
-// CHECK-LABEL: define %struct.float64x1x2_t @test_vld2_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define %struct.float64x1x2_t @test_vld2_dup_f64(double* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x1x2_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.float64x1x2_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.float64x1x2_t* [[__RET]] to i8*
@@ -390,7 +390,7 @@ float64x1x2_t test_vld2_dup_f64(float64_t *a) {
return vld2_dup_f64(a);
}
-// CHECK-LABEL: define %struct.poly64x1x2_t @test_vld2_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.poly64x1x2_t @test_vld2_dup_p64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x1x2_t* [[__RET]] to i8*
@@ -408,7 +408,7 @@ poly64x1x2_t test_vld2_dup_p64(poly64_t *a) {
return vld2_dup_p64(a);
}
-// CHECK-LABEL: define %struct.uint64x2x3_t @test_vld3q_dup_u64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.uint64x2x3_t @test_vld3q_dup_u64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x2x3_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.uint64x2x3_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.uint64x2x3_t* [[__RET]] to i8*
@@ -427,7 +427,7 @@ uint64x2x3_t test_vld3q_dup_u64(uint64_t *a) {
// [{{x[0-9]+|sp}}]
}
-// CHECK-LABEL: define %struct.int64x2x3_t @test_vld3q_dup_s64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.int64x2x3_t @test_vld3q_dup_s64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x2x3_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.int64x2x3_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.int64x2x3_t* [[__RET]] to i8*
@@ -446,7 +446,7 @@ int64x2x3_t test_vld3q_dup_s64(int64_t *a) {
// [{{x[0-9]+|sp}}]
}
-// CHECK-LABEL: define %struct.float64x2x3_t @test_vld3q_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define %struct.float64x2x3_t @test_vld3q_dup_f64(double* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x2x3_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.float64x2x3_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.float64x2x3_t* [[__RET]] to i8*
@@ -465,7 +465,7 @@ float64x2x3_t test_vld3q_dup_f64(float64_t *a) {
// [{{x[0-9]+|sp}}]
}
-// CHECK-LABEL: define %struct.poly64x2x3_t @test_vld3q_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.poly64x2x3_t @test_vld3q_dup_p64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x2x3_t* [[__RET]] to i8*
@@ -484,7 +484,7 @@ poly64x2x3_t test_vld3q_dup_p64(poly64_t *a) {
// [{{x[0-9]+|sp}}]
}
-// CHECK-LABEL: define %struct.float64x1x3_t @test_vld3_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define %struct.float64x1x3_t @test_vld3_dup_f64(double* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x1x3_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.float64x1x3_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.float64x1x3_t* [[__RET]] to i8*
@@ -503,7 +503,7 @@ float64x1x3_t test_vld3_dup_f64(float64_t *a) {
// [{{x[0-9]+|sp}}]
}
-// CHECK-LABEL: define %struct.poly64x1x3_t @test_vld3_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.poly64x1x3_t @test_vld3_dup_p64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x1x3_t* [[__RET]] to i8*
@@ -522,7 +522,7 @@ poly64x1x3_t test_vld3_dup_p64(poly64_t *a) {
// [{{x[0-9]+|sp}}]
}
-// CHECK-LABEL: define %struct.uint64x2x4_t @test_vld4q_dup_u64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.uint64x2x4_t @test_vld4q_dup_u64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x2x4_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.uint64x2x4_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.uint64x2x4_t* [[__RET]] to i8*
@@ -540,7 +540,7 @@ uint64x2x4_t test_vld4q_dup_u64(uint64_t *a) {
return vld4q_dup_u64(a);
}
-// CHECK-LABEL: define %struct.int64x2x4_t @test_vld4q_dup_s64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.int64x2x4_t @test_vld4q_dup_s64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x2x4_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.int64x2x4_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.int64x2x4_t* [[__RET]] to i8*
@@ -558,7 +558,7 @@ int64x2x4_t test_vld4q_dup_s64(int64_t *a) {
return vld4q_dup_s64(a);
}
-// CHECK-LABEL: define %struct.float64x2x4_t @test_vld4q_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define %struct.float64x2x4_t @test_vld4q_dup_f64(double* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x2x4_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.float64x2x4_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.float64x2x4_t* [[__RET]] to i8*
@@ -576,7 +576,7 @@ float64x2x4_t test_vld4q_dup_f64(float64_t *a) {
return vld4q_dup_f64(a);
}
-// CHECK-LABEL: define %struct.poly64x2x4_t @test_vld4q_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.poly64x2x4_t @test_vld4q_dup_p64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x2x4_t* [[__RET]] to i8*
@@ -594,7 +594,7 @@ poly64x2x4_t test_vld4q_dup_p64(poly64_t *a) {
return vld4q_dup_p64(a);
}
-// CHECK-LABEL: define %struct.float64x1x4_t @test_vld4_dup_f64(double* %a) #0 {
+// CHECK-LABEL: define %struct.float64x1x4_t @test_vld4_dup_f64(double* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x1x4_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.float64x1x4_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.float64x1x4_t* [[__RET]] to i8*
@@ -612,7 +612,7 @@ float64x1x4_t test_vld4_dup_f64(float64_t *a) {
return vld4_dup_f64(a);
}
-// CHECK-LABEL: define %struct.poly64x1x4_t @test_vld4_dup_p64(i64* %a) #0 {
+// CHECK-LABEL: define %struct.poly64x1x4_t @test_vld4_dup_p64(i64* %a) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x1x4_t* [[__RET]] to i8*
@@ -786,7 +786,7 @@ poly64x2_t test_vld1q_lane_p64(poly64_t *a, poly64x2_t b) {
return vld1q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define <8 x i8> @test_vld1_lane_u8(i8* %a, <8 x i8> %b) #0 {
+// CHECK-LABEL: define <8 x i8> @test_vld1_lane_u8(i8* %a, <8 x i8> %b) #1 {
// CHECK: [[TMP0:%.*]] = load i8, i8* %a
// CHECK: [[VLD1_LANE:%.*]] = insertelement <8 x i8> %b, i8 [[TMP0]], i32 7
// CHECK: ret <8 x i8> [[VLD1_LANE]]
@@ -794,7 +794,7 @@ uint8x8_t test_vld1_lane_u8(uint8_t *a, uint8x8_t b) {
return vld1_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define <4 x i16> @test_vld1_lane_u16(i16* %a, <4 x i16> %b) #0 {
+// CHECK-LABEL: define <4 x i16> @test_vld1_lane_u16(i16* %a, <4 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x i16> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
@@ -806,7 +806,7 @@ uint16x4_t test_vld1_lane_u16(uint16_t *a, uint16x4_t b) {
return vld1_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define <2 x i32> @test_vld1_lane_u32(i32* %a, <2 x i32> %b) #0 {
+// CHECK-LABEL: define <2 x i32> @test_vld1_lane_u32(i32* %a, <2 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i32* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x i32> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
@@ -818,7 +818,7 @@ uint32x2_t test_vld1_lane_u32(uint32_t *a, uint32x2_t b) {
return vld1_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define <1 x i64> @test_vld1_lane_u64(i64* %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define <1 x i64> @test_vld1_lane_u64(i64* %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
@@ -830,7 +830,7 @@ uint64x1_t test_vld1_lane_u64(uint64_t *a, uint64x1_t b) {
return vld1_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define <8 x i8> @test_vld1_lane_s8(i8* %a, <8 x i8> %b) #0 {
+// CHECK-LABEL: define <8 x i8> @test_vld1_lane_s8(i8* %a, <8 x i8> %b) #1 {
// CHECK: [[TMP0:%.*]] = load i8, i8* %a
// CHECK: [[VLD1_LANE:%.*]] = insertelement <8 x i8> %b, i8 [[TMP0]], i32 7
// CHECK: ret <8 x i8> [[VLD1_LANE]]
@@ -838,7 +838,7 @@ int8x8_t test_vld1_lane_s8(int8_t *a, int8x8_t b) {
return vld1_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define <4 x i16> @test_vld1_lane_s16(i16* %a, <4 x i16> %b) #0 {
+// CHECK-LABEL: define <4 x i16> @test_vld1_lane_s16(i16* %a, <4 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x i16> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
@@ -850,7 +850,7 @@ int16x4_t test_vld1_lane_s16(int16_t *a, int16x4_t b) {
return vld1_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define <2 x i32> @test_vld1_lane_s32(i32* %a, <2 x i32> %b) #0 {
+// CHECK-LABEL: define <2 x i32> @test_vld1_lane_s32(i32* %a, <2 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i32* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x i32> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
@@ -862,7 +862,7 @@ int32x2_t test_vld1_lane_s32(int32_t *a, int32x2_t b) {
return vld1_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define <1 x i64> @test_vld1_lane_s64(i64* %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define <1 x i64> @test_vld1_lane_s64(i64* %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
@@ -874,7 +874,7 @@ int64x1_t test_vld1_lane_s64(int64_t *a, int64x1_t b) {
return vld1_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define <4 x half> @test_vld1_lane_f16(half* %a, <4 x half> %b) #0 {
+// CHECK-LABEL: define <4 x half> @test_vld1_lane_f16(half* %a, <4 x half> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast half* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x half> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half>
@@ -886,7 +886,7 @@ float16x4_t test_vld1_lane_f16(float16_t *a, float16x4_t b) {
return vld1_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define <2 x float> @test_vld1_lane_f32(float* %a, <2 x float> %b) #0 {
+// CHECK-LABEL: define <2 x float> @test_vld1_lane_f32(float* %a, <2 x float> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast float* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
@@ -898,7 +898,7 @@ float32x2_t test_vld1_lane_f32(float32_t *a, float32x2_t b) {
return vld1_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define <1 x double> @test_vld1_lane_f64(double* %a, <1 x double> %b) #0 {
+// CHECK-LABEL: define <1 x double> @test_vld1_lane_f64(double* %a, <1 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast double* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x double> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x double>
@@ -910,7 +910,7 @@ float64x1_t test_vld1_lane_f64(float64_t *a, float64x1_t b) {
return vld1_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define <8 x i8> @test_vld1_lane_p8(i8* %a, <8 x i8> %b) #0 {
+// CHECK-LABEL: define <8 x i8> @test_vld1_lane_p8(i8* %a, <8 x i8> %b) #1 {
// CHECK: [[TMP0:%.*]] = load i8, i8* %a
// CHECK: [[VLD1_LANE:%.*]] = insertelement <8 x i8> %b, i8 [[TMP0]], i32 7
// CHECK: ret <8 x i8> [[VLD1_LANE]]
@@ -918,7 +918,7 @@ poly8x8_t test_vld1_lane_p8(poly8_t *a, poly8x8_t b) {
return vld1_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define <4 x i16> @test_vld1_lane_p16(i16* %a, <4 x i16> %b) #0 {
+// CHECK-LABEL: define <4 x i16> @test_vld1_lane_p16(i16* %a, <4 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x i16> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
@@ -930,7 +930,7 @@ poly16x4_t test_vld1_lane_p16(poly16_t *a, poly16x4_t b) {
return vld1_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define <1 x i64> @test_vld1_lane_p64(i64* %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define <1 x i64> @test_vld1_lane_p64(i64* %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
@@ -942,7 +942,7 @@ poly64x1_t test_vld1_lane_p64(poly64_t *a, poly64x1_t b) {
return vld1_lane_p64(a, b, 0);
}
-// CHECK-LABEL: define %struct.int8x16x2_t @test_vld2q_lane_s8(i8* %ptr, [2 x <16 x i8>] %src.coerce) #0 {
+// CHECK-LABEL: define %struct.int8x16x2_t @test_vld2q_lane_s8(i8* %ptr, [2 x <16 x i8>] %src.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[SRC:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int8x16x2_t, align 16
@@ -971,7 +971,7 @@ int8x16x2_t test_vld2q_lane_s8(int8_t const * ptr, int8x16x2_t src) {
return vld2q_lane_s8(ptr, src, 15);
}
-// CHECK-LABEL: define %struct.uint8x16x2_t @test_vld2q_lane_u8(i8* %ptr, [2 x <16 x i8>] %src.coerce) #0 {
+// CHECK-LABEL: define %struct.uint8x16x2_t @test_vld2q_lane_u8(i8* %ptr, [2 x <16 x i8>] %src.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[SRC:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x16x2_t, align 16
@@ -1000,7 +1000,7 @@ uint8x16x2_t test_vld2q_lane_u8(uint8_t const * ptr, uint8x16x2_t src) {
return vld2q_lane_u8(ptr, src, 15);
}
-// CHECK-LABEL: define %struct.poly8x16x2_t @test_vld2q_lane_p8(i8* %ptr, [2 x <16 x i8>] %src.coerce) #0 {
+// CHECK-LABEL: define %struct.poly8x16x2_t @test_vld2q_lane_p8(i8* %ptr, [2 x <16 x i8>] %src.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[SRC:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x16x2_t, align 16
@@ -1029,7 +1029,7 @@ poly8x16x2_t test_vld2q_lane_p8(poly8_t const * ptr, poly8x16x2_t src) {
return vld2q_lane_p8(ptr, src, 15);
}
-// CHECK-LABEL: define %struct.int8x16x3_t @test_vld3q_lane_s8(i8* %ptr, [3 x <16 x i8>] %src.coerce) #0 {
+// CHECK-LABEL: define %struct.int8x16x3_t @test_vld3q_lane_s8(i8* %ptr, [3 x <16 x i8>] %src.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[SRC:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int8x16x3_t, align 16
@@ -1061,7 +1061,7 @@ int8x16x3_t test_vld3q_lane_s8(int8_t const * ptr, int8x16x3_t src) {
return vld3q_lane_s8(ptr, src, 15);
}
-// CHECK-LABEL: define %struct.uint8x16x3_t @test_vld3q_lane_u8(i8* %ptr, [3 x <16 x i8>] %src.coerce) #0 {
+// CHECK-LABEL: define %struct.uint8x16x3_t @test_vld3q_lane_u8(i8* %ptr, [3 x <16 x i8>] %src.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[SRC:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x16x3_t, align 16
@@ -1093,7 +1093,7 @@ uint8x16x3_t test_vld3q_lane_u8(uint8_t const * ptr, uint8x16x3_t src) {
return vld3q_lane_u8(ptr, src, 15);
}
-// CHECK-LABEL: define %struct.uint16x8x2_t @test_vld2q_lane_u16(i16* %a, [2 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint16x8x2_t @test_vld2q_lane_u16(i16* %a, [2 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint16x8x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x8x2_t, align 16
@@ -1127,7 +1127,7 @@ uint16x8x2_t test_vld2q_lane_u16(uint16_t *a, uint16x8x2_t b) {
return vld2q_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define %struct.uint32x4x2_t @test_vld2q_lane_u32(i32* %a, [2 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint32x4x2_t @test_vld2q_lane_u32(i32* %a, [2 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint32x4x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint32x4x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x4x2_t, align 16
@@ -1161,7 +1161,7 @@ uint32x4x2_t test_vld2q_lane_u32(uint32_t *a, uint32x4x2_t b) {
return vld2q_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define %struct.uint64x2x2_t @test_vld2q_lane_u64(i64* %a, [2 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint64x2x2_t @test_vld2q_lane_u64(i64* %a, [2 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x2x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x2x2_t, align 16
@@ -1195,7 +1195,7 @@ uint64x2x2_t test_vld2q_lane_u64(uint64_t *a, uint64x2x2_t b) {
return vld2q_lane_u64(a, b, 1);
}
-// CHECK-LABEL: define %struct.int16x8x2_t @test_vld2q_lane_s16(i16* %a, [2 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int16x8x2_t @test_vld2q_lane_s16(i16* %a, [2 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int16x8x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int16x8x2_t, align 16
@@ -1229,7 +1229,7 @@ int16x8x2_t test_vld2q_lane_s16(int16_t *a, int16x8x2_t b) {
return vld2q_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define %struct.int32x4x2_t @test_vld2q_lane_s32(i32* %a, [2 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int32x4x2_t @test_vld2q_lane_s32(i32* %a, [2 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int32x4x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int32x4x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int32x4x2_t, align 16
@@ -1263,7 +1263,7 @@ int32x4x2_t test_vld2q_lane_s32(int32_t *a, int32x4x2_t b) {
return vld2q_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define %struct.int64x2x2_t @test_vld2q_lane_s64(i64* %a, [2 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int64x2x2_t @test_vld2q_lane_s64(i64* %a, [2 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x2x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int64x2x2_t, align 16
@@ -1297,7 +1297,7 @@ int64x2x2_t test_vld2q_lane_s64(int64_t *a, int64x2x2_t b) {
return vld2q_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define %struct.float16x8x2_t @test_vld2q_lane_f16(half* %a, [2 x <8 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float16x8x2_t @test_vld2q_lane_f16(half* %a, [2 x <8 x half>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float16x8x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float16x8x2_t, align 16
@@ -1331,7 +1331,7 @@ float16x8x2_t test_vld2q_lane_f16(float16_t *a, float16x8x2_t b) {
return vld2q_lane_f16(a, b, 7);
}
-// CHECK-LABEL: define %struct.float32x4x2_t @test_vld2q_lane_f32(float* %a, [2 x <4 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float32x4x2_t @test_vld2q_lane_f32(float* %a, [2 x <4 x float>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float32x4x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float32x4x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float32x4x2_t, align 16
@@ -1365,7 +1365,7 @@ float32x4x2_t test_vld2q_lane_f32(float32_t *a, float32x4x2_t b) {
return vld2q_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define %struct.float64x2x2_t @test_vld2q_lane_f64(double* %a, [2 x <2 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float64x2x2_t @test_vld2q_lane_f64(double* %a, [2 x <2 x double>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x2x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float64x2x2_t, align 16
@@ -1399,7 +1399,7 @@ float64x2x2_t test_vld2q_lane_f64(float64_t *a, float64x2x2_t b) {
return vld2q_lane_f64(a, b, 1);
}
-// CHECK-LABEL: define %struct.poly16x8x2_t @test_vld2q_lane_p16(i16* %a, [2 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly16x8x2_t @test_vld2q_lane_p16(i16* %a, [2 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly16x8x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x8x2_t, align 16
@@ -1433,7 +1433,7 @@ poly16x8x2_t test_vld2q_lane_p16(poly16_t *a, poly16x8x2_t b) {
return vld2q_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define %struct.poly64x2x2_t @test_vld2q_lane_p64(i64* %a, [2 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly64x2x2_t @test_vld2q_lane_p64(i64* %a, [2 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x2_t, align 16
@@ -1467,7 +1467,7 @@ poly64x2x2_t test_vld2q_lane_p64(poly64_t *a, poly64x2x2_t b) {
return vld2q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define %struct.uint8x8x2_t @test_vld2_lane_u8(i8* %a, [2 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint8x8x2_t @test_vld2_lane_u8(i8* %a, [2 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint8x8x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint8x8x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x8x2_t, align 8
@@ -1496,7 +1496,7 @@ uint8x8x2_t test_vld2_lane_u8(uint8_t *a, uint8x8x2_t b) {
return vld2_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define %struct.uint16x4x2_t @test_vld2_lane_u16(i16* %a, [2 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint16x4x2_t @test_vld2_lane_u16(i16* %a, [2 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint16x4x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x4x2_t, align 8
@@ -1530,7 +1530,7 @@ uint16x4x2_t test_vld2_lane_u16(uint16_t *a, uint16x4x2_t b) {
return vld2_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define %struct.uint32x2x2_t @test_vld2_lane_u32(i32* %a, [2 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint32x2x2_t @test_vld2_lane_u32(i32* %a, [2 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint32x2x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint32x2x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x2x2_t, align 8
@@ -1564,7 +1564,7 @@ uint32x2x2_t test_vld2_lane_u32(uint32_t *a, uint32x2x2_t b) {
return vld2_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define %struct.uint64x1x2_t @test_vld2_lane_u64(i64* %a, [2 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint64x1x2_t @test_vld2_lane_u64(i64* %a, [2 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x1x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x1x2_t, align 8
@@ -1598,7 +1598,7 @@ uint64x1x2_t test_vld2_lane_u64(uint64_t *a, uint64x1x2_t b) {
return vld2_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define %struct.int8x8x2_t @test_vld2_lane_s8(i8* %a, [2 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int8x8x2_t @test_vld2_lane_s8(i8* %a, [2 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int8x8x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int8x8x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int8x8x2_t, align 8
@@ -1627,7 +1627,7 @@ int8x8x2_t test_vld2_lane_s8(int8_t *a, int8x8x2_t b) {
return vld2_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define %struct.int16x4x2_t @test_vld2_lane_s16(i16* %a, [2 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int16x4x2_t @test_vld2_lane_s16(i16* %a, [2 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int16x4x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int16x4x2_t, align 8
@@ -1661,7 +1661,7 @@ int16x4x2_t test_vld2_lane_s16(int16_t *a, int16x4x2_t b) {
return vld2_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define %struct.int32x2x2_t @test_vld2_lane_s32(i32* %a, [2 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int32x2x2_t @test_vld2_lane_s32(i32* %a, [2 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int32x2x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int32x2x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int32x2x2_t, align 8
@@ -1695,7 +1695,7 @@ int32x2x2_t test_vld2_lane_s32(int32_t *a, int32x2x2_t b) {
return vld2_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define %struct.int64x1x2_t @test_vld2_lane_s64(i64* %a, [2 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int64x1x2_t @test_vld2_lane_s64(i64* %a, [2 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x1x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int64x1x2_t, align 8
@@ -1729,7 +1729,7 @@ int64x1x2_t test_vld2_lane_s64(int64_t *a, int64x1x2_t b) {
return vld2_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define %struct.float16x4x2_t @test_vld2_lane_f16(half* %a, [2 x <4 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float16x4x2_t @test_vld2_lane_f16(half* %a, [2 x <4 x half>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float16x4x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float16x4x2_t, align 8
@@ -1763,7 +1763,7 @@ float16x4x2_t test_vld2_lane_f16(float16_t *a, float16x4x2_t b) {
return vld2_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define %struct.float32x2x2_t @test_vld2_lane_f32(float* %a, [2 x <2 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float32x2x2_t @test_vld2_lane_f32(float* %a, [2 x <2 x float>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float32x2x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float32x2x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float32x2x2_t, align 8
@@ -1797,7 +1797,7 @@ float32x2x2_t test_vld2_lane_f32(float32_t *a, float32x2x2_t b) {
return vld2_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define %struct.float64x1x2_t @test_vld2_lane_f64(double* %a, [2 x <1 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float64x1x2_t @test_vld2_lane_f64(double* %a, [2 x <1 x double>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x1x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float64x1x2_t, align 8
@@ -1831,7 +1831,7 @@ float64x1x2_t test_vld2_lane_f64(float64_t *a, float64x1x2_t b) {
return vld2_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define %struct.poly8x8x2_t @test_vld2_lane_p8(i8* %a, [2 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly8x8x2_t @test_vld2_lane_p8(i8* %a, [2 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly8x8x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly8x8x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x8x2_t, align 8
@@ -1860,7 +1860,7 @@ poly8x8x2_t test_vld2_lane_p8(poly8_t *a, poly8x8x2_t b) {
return vld2_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define %struct.poly16x4x2_t @test_vld2_lane_p16(i16* %a, [2 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly16x4x2_t @test_vld2_lane_p16(i16* %a, [2 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly16x4x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x4x2_t, align 8
@@ -1894,7 +1894,7 @@ poly16x4x2_t test_vld2_lane_p16(poly16_t *a, poly16x4x2_t b) {
return vld2_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define %struct.poly64x1x2_t @test_vld2_lane_p64(i64* %a, [2 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly64x1x2_t @test_vld2_lane_p64(i64* %a, [2 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x2_t, align 8
@@ -1928,7 +1928,7 @@ poly64x1x2_t test_vld2_lane_p64(poly64_t *a, poly64x1x2_t b) {
return vld2_lane_p64(a, b, 0);
}
-// CHECK-LABEL: define %struct.uint16x8x3_t @test_vld3q_lane_u16(i16* %a, [3 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint16x8x3_t @test_vld3q_lane_u16(i16* %a, [3 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint16x8x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x8x3_t, align 16
@@ -1967,7 +1967,7 @@ uint16x8x3_t test_vld3q_lane_u16(uint16_t *a, uint16x8x3_t b) {
return vld3q_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define %struct.uint32x4x3_t @test_vld3q_lane_u32(i32* %a, [3 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint32x4x3_t @test_vld3q_lane_u32(i32* %a, [3 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint32x4x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint32x4x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x4x3_t, align 16
@@ -2006,7 +2006,7 @@ uint32x4x3_t test_vld3q_lane_u32(uint32_t *a, uint32x4x3_t b) {
return vld3q_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define %struct.uint64x2x3_t @test_vld3q_lane_u64(i64* %a, [3 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint64x2x3_t @test_vld3q_lane_u64(i64* %a, [3 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x2x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x2x3_t, align 16
@@ -2045,7 +2045,7 @@ uint64x2x3_t test_vld3q_lane_u64(uint64_t *a, uint64x2x3_t b) {
return vld3q_lane_u64(a, b, 1);
}
-// CHECK-LABEL: define %struct.int16x8x3_t @test_vld3q_lane_s16(i16* %a, [3 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int16x8x3_t @test_vld3q_lane_s16(i16* %a, [3 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int16x8x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int16x8x3_t, align 16
@@ -2084,7 +2084,7 @@ int16x8x3_t test_vld3q_lane_s16(int16_t *a, int16x8x3_t b) {
return vld3q_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define %struct.int32x4x3_t @test_vld3q_lane_s32(i32* %a, [3 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int32x4x3_t @test_vld3q_lane_s32(i32* %a, [3 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int32x4x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int32x4x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int32x4x3_t, align 16
@@ -2123,7 +2123,7 @@ int32x4x3_t test_vld3q_lane_s32(int32_t *a, int32x4x3_t b) {
return vld3q_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define %struct.int64x2x3_t @test_vld3q_lane_s64(i64* %a, [3 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int64x2x3_t @test_vld3q_lane_s64(i64* %a, [3 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x2x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int64x2x3_t, align 16
@@ -2162,7 +2162,7 @@ int64x2x3_t test_vld3q_lane_s64(int64_t *a, int64x2x3_t b) {
return vld3q_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define %struct.float16x8x3_t @test_vld3q_lane_f16(half* %a, [3 x <8 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float16x8x3_t @test_vld3q_lane_f16(half* %a, [3 x <8 x half>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float16x8x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float16x8x3_t, align 16
@@ -2201,7 +2201,7 @@ float16x8x3_t test_vld3q_lane_f16(float16_t *a, float16x8x3_t b) {
return vld3q_lane_f16(a, b, 7);
}
-// CHECK-LABEL: define %struct.float32x4x3_t @test_vld3q_lane_f32(float* %a, [3 x <4 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float32x4x3_t @test_vld3q_lane_f32(float* %a, [3 x <4 x float>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float32x4x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float32x4x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float32x4x3_t, align 16
@@ -2240,7 +2240,7 @@ float32x4x3_t test_vld3q_lane_f32(float32_t *a, float32x4x3_t b) {
return vld3q_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define %struct.float64x2x3_t @test_vld3q_lane_f64(double* %a, [3 x <2 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float64x2x3_t @test_vld3q_lane_f64(double* %a, [3 x <2 x double>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x2x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float64x2x3_t, align 16
@@ -2279,7 +2279,7 @@ float64x2x3_t test_vld3q_lane_f64(float64_t *a, float64x2x3_t b) {
return vld3q_lane_f64(a, b, 1);
}
-// CHECK-LABEL: define %struct.poly8x16x3_t @test_vld3q_lane_p8(i8* %a, [3 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly8x16x3_t @test_vld3q_lane_p8(i8* %a, [3 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x16x3_t, align 16
@@ -2311,7 +2311,7 @@ poly8x16x3_t test_vld3q_lane_p8(poly8_t *a, poly8x16x3_t b) {
return vld3q_lane_p8(a, b, 15);
}
-// CHECK-LABEL: define %struct.poly16x8x3_t @test_vld3q_lane_p16(i16* %a, [3 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly16x8x3_t @test_vld3q_lane_p16(i16* %a, [3 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly16x8x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x8x3_t, align 16
@@ -2350,7 +2350,7 @@ poly16x8x3_t test_vld3q_lane_p16(poly16_t *a, poly16x8x3_t b) {
return vld3q_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define %struct.poly64x2x3_t @test_vld3q_lane_p64(i64* %a, [3 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly64x2x3_t @test_vld3q_lane_p64(i64* %a, [3 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x3_t, align 16
@@ -2389,7 +2389,7 @@ poly64x2x3_t test_vld3q_lane_p64(poly64_t *a, poly64x2x3_t b) {
return vld3q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define %struct.uint8x8x3_t @test_vld3_lane_u8(i8* %a, [3 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint8x8x3_t @test_vld3_lane_u8(i8* %a, [3 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint8x8x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint8x8x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x8x3_t, align 8
@@ -2421,7 +2421,7 @@ uint8x8x3_t test_vld3_lane_u8(uint8_t *a, uint8x8x3_t b) {
return vld3_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define %struct.uint16x4x3_t @test_vld3_lane_u16(i16* %a, [3 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint16x4x3_t @test_vld3_lane_u16(i16* %a, [3 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint16x4x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x4x3_t, align 8
@@ -2460,7 +2460,7 @@ uint16x4x3_t test_vld3_lane_u16(uint16_t *a, uint16x4x3_t b) {
return vld3_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define %struct.uint32x2x3_t @test_vld3_lane_u32(i32* %a, [3 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint32x2x3_t @test_vld3_lane_u32(i32* %a, [3 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint32x2x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint32x2x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x2x3_t, align 8
@@ -2499,7 +2499,7 @@ uint32x2x3_t test_vld3_lane_u32(uint32_t *a, uint32x2x3_t b) {
return vld3_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define %struct.uint64x1x3_t @test_vld3_lane_u64(i64* %a, [3 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint64x1x3_t @test_vld3_lane_u64(i64* %a, [3 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x1x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x1x3_t, align 8
@@ -2538,7 +2538,7 @@ uint64x1x3_t test_vld3_lane_u64(uint64_t *a, uint64x1x3_t b) {
return vld3_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define %struct.int8x8x3_t @test_vld3_lane_s8(i8* %a, [3 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int8x8x3_t @test_vld3_lane_s8(i8* %a, [3 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int8x8x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int8x8x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int8x8x3_t, align 8
@@ -2570,7 +2570,7 @@ int8x8x3_t test_vld3_lane_s8(int8_t *a, int8x8x3_t b) {
return vld3_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define %struct.int16x4x3_t @test_vld3_lane_s16(i16* %a, [3 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int16x4x3_t @test_vld3_lane_s16(i16* %a, [3 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int16x4x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int16x4x3_t, align 8
@@ -2609,7 +2609,7 @@ int16x4x3_t test_vld3_lane_s16(int16_t *a, int16x4x3_t b) {
return vld3_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define %struct.int32x2x3_t @test_vld3_lane_s32(i32* %a, [3 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int32x2x3_t @test_vld3_lane_s32(i32* %a, [3 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int32x2x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int32x2x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int32x2x3_t, align 8
@@ -2648,7 +2648,7 @@ int32x2x3_t test_vld3_lane_s32(int32_t *a, int32x2x3_t b) {
return vld3_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define %struct.int64x1x3_t @test_vld3_lane_s64(i64* %a, [3 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int64x1x3_t @test_vld3_lane_s64(i64* %a, [3 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x1x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int64x1x3_t, align 8
@@ -2687,7 +2687,7 @@ int64x1x3_t test_vld3_lane_s64(int64_t *a, int64x1x3_t b) {
return vld3_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define %struct.float16x4x3_t @test_vld3_lane_f16(half* %a, [3 x <4 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float16x4x3_t @test_vld3_lane_f16(half* %a, [3 x <4 x half>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float16x4x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float16x4x3_t, align 8
@@ -2726,7 +2726,7 @@ float16x4x3_t test_vld3_lane_f16(float16_t *a, float16x4x3_t b) {
return vld3_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define %struct.float32x2x3_t @test_vld3_lane_f32(float* %a, [3 x <2 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float32x2x3_t @test_vld3_lane_f32(float* %a, [3 x <2 x float>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float32x2x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float32x2x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float32x2x3_t, align 8
@@ -2765,7 +2765,7 @@ float32x2x3_t test_vld3_lane_f32(float32_t *a, float32x2x3_t b) {
return vld3_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define %struct.float64x1x3_t @test_vld3_lane_f64(double* %a, [3 x <1 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float64x1x3_t @test_vld3_lane_f64(double* %a, [3 x <1 x double>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x1x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float64x1x3_t, align 8
@@ -2804,7 +2804,7 @@ float64x1x3_t test_vld3_lane_f64(float64_t *a, float64x1x3_t b) {
return vld3_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define %struct.poly8x8x3_t @test_vld3_lane_p8(i8* %a, [3 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly8x8x3_t @test_vld3_lane_p8(i8* %a, [3 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly8x8x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly8x8x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x8x3_t, align 8
@@ -2836,7 +2836,7 @@ poly8x8x3_t test_vld3_lane_p8(poly8_t *a, poly8x8x3_t b) {
return vld3_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define %struct.poly16x4x3_t @test_vld3_lane_p16(i16* %a, [3 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly16x4x3_t @test_vld3_lane_p16(i16* %a, [3 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly16x4x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x4x3_t, align 8
@@ -2875,7 +2875,7 @@ poly16x4x3_t test_vld3_lane_p16(poly16_t *a, poly16x4x3_t b) {
return vld3_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define %struct.poly64x1x3_t @test_vld3_lane_p64(i64* %a, [3 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly64x1x3_t @test_vld3_lane_p64(i64* %a, [3 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x3_t, align 8
@@ -2914,7 +2914,7 @@ poly64x1x3_t test_vld3_lane_p64(poly64_t *a, poly64x1x3_t b) {
return vld3_lane_p64(a, b, 0);
}
-// CHECK-LABEL: define %struct.uint8x16x4_t @test_vld4q_lane_u8(i8* %a, [4 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint8x16x4_t @test_vld4q_lane_u8(i8* %a, [4 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x16x4_t, align 16
@@ -2949,7 +2949,7 @@ uint8x16x4_t test_vld4q_lane_u8(uint8_t *a, uint8x16x4_t b) {
return vld4q_lane_u8(a, b, 15);
}
-// CHECK-LABEL: define %struct.uint16x8x4_t @test_vld4q_lane_u16(i16* %a, [4 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint16x8x4_t @test_vld4q_lane_u16(i16* %a, [4 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint16x8x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x8x4_t, align 16
@@ -2993,7 +2993,7 @@ uint16x8x4_t test_vld4q_lane_u16(uint16_t *a, uint16x8x4_t b) {
return vld4q_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define %struct.uint32x4x4_t @test_vld4q_lane_u32(i32* %a, [4 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint32x4x4_t @test_vld4q_lane_u32(i32* %a, [4 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint32x4x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint32x4x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x4x4_t, align 16
@@ -3037,7 +3037,7 @@ uint32x4x4_t test_vld4q_lane_u32(uint32_t *a, uint32x4x4_t b) {
return vld4q_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define %struct.uint64x2x4_t @test_vld4q_lane_u64(i64* %a, [4 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint64x2x4_t @test_vld4q_lane_u64(i64* %a, [4 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x2x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x2x4_t, align 16
@@ -3081,7 +3081,7 @@ uint64x2x4_t test_vld4q_lane_u64(uint64_t *a, uint64x2x4_t b) {
return vld4q_lane_u64(a, b, 1);
}
-// CHECK-LABEL: define %struct.int8x16x4_t @test_vld4q_lane_s8(i8* %a, [4 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int8x16x4_t @test_vld4q_lane_s8(i8* %a, [4 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int8x16x4_t, align 16
@@ -3116,7 +3116,7 @@ int8x16x4_t test_vld4q_lane_s8(int8_t *a, int8x16x4_t b) {
return vld4q_lane_s8(a, b, 15);
}
-// CHECK-LABEL: define %struct.int16x8x4_t @test_vld4q_lane_s16(i16* %a, [4 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int16x8x4_t @test_vld4q_lane_s16(i16* %a, [4 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int16x8x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int16x8x4_t, align 16
@@ -3160,7 +3160,7 @@ int16x8x4_t test_vld4q_lane_s16(int16_t *a, int16x8x4_t b) {
return vld4q_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define %struct.int32x4x4_t @test_vld4q_lane_s32(i32* %a, [4 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int32x4x4_t @test_vld4q_lane_s32(i32* %a, [4 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int32x4x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int32x4x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int32x4x4_t, align 16
@@ -3204,7 +3204,7 @@ int32x4x4_t test_vld4q_lane_s32(int32_t *a, int32x4x4_t b) {
return vld4q_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define %struct.int64x2x4_t @test_vld4q_lane_s64(i64* %a, [4 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int64x2x4_t @test_vld4q_lane_s64(i64* %a, [4 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x2x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int64x2x4_t, align 16
@@ -3248,7 +3248,7 @@ int64x2x4_t test_vld4q_lane_s64(int64_t *a, int64x2x4_t b) {
return vld4q_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define %struct.float16x8x4_t @test_vld4q_lane_f16(half* %a, [4 x <8 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float16x8x4_t @test_vld4q_lane_f16(half* %a, [4 x <8 x half>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float16x8x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float16x8x4_t, align 16
@@ -3292,7 +3292,7 @@ float16x8x4_t test_vld4q_lane_f16(float16_t *a, float16x8x4_t b) {
return vld4q_lane_f16(a, b, 7);
}
-// CHECK-LABEL: define %struct.float32x4x4_t @test_vld4q_lane_f32(float* %a, [4 x <4 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float32x4x4_t @test_vld4q_lane_f32(float* %a, [4 x <4 x float>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float32x4x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float32x4x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float32x4x4_t, align 16
@@ -3336,7 +3336,7 @@ float32x4x4_t test_vld4q_lane_f32(float32_t *a, float32x4x4_t b) {
return vld4q_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define %struct.float64x2x4_t @test_vld4q_lane_f64(double* %a, [4 x <2 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float64x2x4_t @test_vld4q_lane_f64(double* %a, [4 x <2 x double>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x2x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.float64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float64x2x4_t, align 16
@@ -3380,7 +3380,7 @@ float64x2x4_t test_vld4q_lane_f64(float64_t *a, float64x2x4_t b) {
return vld4q_lane_f64(a, b, 1);
}
-// CHECK-LABEL: define %struct.poly8x16x4_t @test_vld4q_lane_p8(i8* %a, [4 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly8x16x4_t @test_vld4q_lane_p8(i8* %a, [4 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x16x4_t, align 16
@@ -3415,7 +3415,7 @@ poly8x16x4_t test_vld4q_lane_p8(poly8_t *a, poly8x16x4_t b) {
return vld4q_lane_p8(a, b, 15);
}
-// CHECK-LABEL: define %struct.poly16x8x4_t @test_vld4q_lane_p16(i16* %a, [4 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly16x8x4_t @test_vld4q_lane_p16(i16* %a, [4 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly16x8x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x8x4_t, align 16
@@ -3459,7 +3459,7 @@ poly16x8x4_t test_vld4q_lane_p16(poly16_t *a, poly16x8x4_t b) {
return vld4q_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define %struct.poly64x2x4_t @test_vld4q_lane_p64(i64* %a, [4 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly64x2x4_t @test_vld4q_lane_p64(i64* %a, [4 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x4_t, align 16
@@ -3503,7 +3503,7 @@ poly64x2x4_t test_vld4q_lane_p64(poly64_t *a, poly64x2x4_t b) {
return vld4q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define %struct.uint8x8x4_t @test_vld4_lane_u8(i8* %a, [4 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint8x8x4_t @test_vld4_lane_u8(i8* %a, [4 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint8x8x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint8x8x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x8x4_t, align 8
@@ -3538,7 +3538,7 @@ uint8x8x4_t test_vld4_lane_u8(uint8_t *a, uint8x8x4_t b) {
return vld4_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define %struct.uint16x4x4_t @test_vld4_lane_u16(i16* %a, [4 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint16x4x4_t @test_vld4_lane_u16(i16* %a, [4 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint16x4x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x4x4_t, align 8
@@ -3582,7 +3582,7 @@ uint16x4x4_t test_vld4_lane_u16(uint16_t *a, uint16x4x4_t b) {
return vld4_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define %struct.uint32x2x4_t @test_vld4_lane_u32(i32* %a, [4 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint32x2x4_t @test_vld4_lane_u32(i32* %a, [4 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint32x2x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint32x2x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x2x4_t, align 8
@@ -3626,7 +3626,7 @@ uint32x2x4_t test_vld4_lane_u32(uint32_t *a, uint32x2x4_t b) {
return vld4_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define %struct.uint64x1x4_t @test_vld4_lane_u64(i64* %a, [4 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.uint64x1x4_t @test_vld4_lane_u64(i64* %a, [4 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.uint64x1x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.uint64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x1x4_t, align 8
@@ -3670,7 +3670,7 @@ uint64x1x4_t test_vld4_lane_u64(uint64_t *a, uint64x1x4_t b) {
return vld4_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define %struct.int8x8x4_t @test_vld4_lane_s8(i8* %a, [4 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int8x8x4_t @test_vld4_lane_s8(i8* %a, [4 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int8x8x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int8x8x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int8x8x4_t, align 8
@@ -3705,7 +3705,7 @@ int8x8x4_t test_vld4_lane_s8(int8_t *a, int8x8x4_t b) {
return vld4_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define %struct.int16x4x4_t @test_vld4_lane_s16(i16* %a, [4 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int16x4x4_t @test_vld4_lane_s16(i16* %a, [4 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int16x4x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int16x4x4_t, align 8
@@ -3749,7 +3749,7 @@ int16x4x4_t test_vld4_lane_s16(int16_t *a, int16x4x4_t b) {
return vld4_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define %struct.int32x2x4_t @test_vld4_lane_s32(i32* %a, [4 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int32x2x4_t @test_vld4_lane_s32(i32* %a, [4 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int32x2x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int32x2x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int32x2x4_t, align 8
@@ -3793,7 +3793,7 @@ int32x2x4_t test_vld4_lane_s32(int32_t *a, int32x2x4_t b) {
return vld4_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define %struct.int64x1x4_t @test_vld4_lane_s64(i64* %a, [4 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.int64x1x4_t @test_vld4_lane_s64(i64* %a, [4 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.int64x1x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.int64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int64x1x4_t, align 8
@@ -3837,7 +3837,7 @@ int64x1x4_t test_vld4_lane_s64(int64_t *a, int64x1x4_t b) {
return vld4_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define %struct.float16x4x4_t @test_vld4_lane_f16(half* %a, [4 x <4 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float16x4x4_t @test_vld4_lane_f16(half* %a, [4 x <4 x half>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float16x4x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float16x4x4_t, align 8
@@ -3881,7 +3881,7 @@ float16x4x4_t test_vld4_lane_f16(float16_t *a, float16x4x4_t b) {
return vld4_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define %struct.float32x2x4_t @test_vld4_lane_f32(float* %a, [4 x <2 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float32x2x4_t @test_vld4_lane_f32(float* %a, [4 x <2 x float>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float32x2x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float32x2x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float32x2x4_t, align 8
@@ -3925,7 +3925,7 @@ float32x2x4_t test_vld4_lane_f32(float32_t *a, float32x2x4_t b) {
return vld4_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define %struct.float64x1x4_t @test_vld4_lane_f64(double* %a, [4 x <1 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.float64x1x4_t @test_vld4_lane_f64(double* %a, [4 x <1 x double>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.float64x1x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.float64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float64x1x4_t, align 8
@@ -3969,7 +3969,7 @@ float64x1x4_t test_vld4_lane_f64(float64_t *a, float64x1x4_t b) {
return vld4_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define %struct.poly8x8x4_t @test_vld4_lane_p8(i8* %a, [4 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly8x8x4_t @test_vld4_lane_p8(i8* %a, [4 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly8x8x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly8x8x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x8x4_t, align 8
@@ -4004,7 +4004,7 @@ poly8x8x4_t test_vld4_lane_p8(poly8_t *a, poly8x8x4_t b) {
return vld4_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define %struct.poly16x4x4_t @test_vld4_lane_p16(i16* %a, [4 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly16x4x4_t @test_vld4_lane_p16(i16* %a, [4 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly16x4x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x4x4_t, align 8
@@ -4048,7 +4048,7 @@ poly16x4x4_t test_vld4_lane_p16(poly16_t *a, poly16x4x4_t b) {
return vld4_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define %struct.poly64x1x4_t @test_vld4_lane_p64(i64* %a, [4 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define %struct.poly64x1x4_t @test_vld4_lane_p64(i64* %a, [4 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[B:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x4_t, align 8
@@ -4248,7 +4248,7 @@ void test_vst1q_lane_p64(poly64_t *a, poly64x2_t b) {
vst1q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst1_lane_u8(i8* %a, <8 x i8> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_u8(i8* %a, <8 x i8> %b) #1 {
// CHECK: [[TMP0:%.*]] = extractelement <8 x i8> %b, i32 7
// CHECK: store i8 [[TMP0]], i8* %a
// CHECK: ret void
@@ -4256,7 +4256,7 @@ void test_vst1_lane_u8(uint8_t *a, uint8x8_t b) {
vst1_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst1_lane_u16(i16* %a, <4 x i16> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_u16(i16* %a, <4 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x i16> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
@@ -4268,7 +4268,7 @@ void test_vst1_lane_u16(uint16_t *a, uint16x4_t b) {
vst1_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst1_lane_u32(i32* %a, <2 x i32> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_u32(i32* %a, <2 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i32* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x i32> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
@@ -4280,7 +4280,7 @@ void test_vst1_lane_u32(uint32_t *a, uint32x2_t b) {
vst1_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst1_lane_u64(i64* %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_u64(i64* %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
@@ -4292,7 +4292,7 @@ void test_vst1_lane_u64(uint64_t *a, uint64x1_t b) {
vst1_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst1_lane_s8(i8* %a, <8 x i8> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_s8(i8* %a, <8 x i8> %b) #1 {
// CHECK: [[TMP0:%.*]] = extractelement <8 x i8> %b, i32 7
// CHECK: store i8 [[TMP0]], i8* %a
// CHECK: ret void
@@ -4300,7 +4300,7 @@ void test_vst1_lane_s8(int8_t *a, int8x8_t b) {
vst1_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst1_lane_s16(i16* %a, <4 x i16> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_s16(i16* %a, <4 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x i16> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
@@ -4312,7 +4312,7 @@ void test_vst1_lane_s16(int16_t *a, int16x4_t b) {
vst1_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst1_lane_s32(i32* %a, <2 x i32> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_s32(i32* %a, <2 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i32* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x i32> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
@@ -4324,7 +4324,7 @@ void test_vst1_lane_s32(int32_t *a, int32x2_t b) {
vst1_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst1_lane_s64(i64* %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_s64(i64* %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
@@ -4336,7 +4336,7 @@ void test_vst1_lane_s64(int64_t *a, int64x1_t b) {
vst1_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst1_lane_f16(half* %a, <4 x half> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_f16(half* %a, <4 x half> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast half* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x half> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half>
@@ -4348,7 +4348,7 @@ void test_vst1_lane_f16(float16_t *a, float16x4_t b) {
vst1_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst1_lane_f32(float* %a, <2 x float> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_f32(float* %a, <2 x float> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast float* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
@@ -4360,7 +4360,7 @@ void test_vst1_lane_f32(float32_t *a, float32x2_t b) {
vst1_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst1_lane_f64(double* %a, <1 x double> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_f64(double* %a, <1 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast double* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x double> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x double>
@@ -4372,7 +4372,7 @@ void test_vst1_lane_f64(float64_t *a, float64x1_t b) {
vst1_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst1_lane_p8(i8* %a, <8 x i8> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_p8(i8* %a, <8 x i8> %b) #1 {
// CHECK: [[TMP0:%.*]] = extractelement <8 x i8> %b, i32 7
// CHECK: store i8 [[TMP0]], i8* %a
// CHECK: ret void
@@ -4380,7 +4380,7 @@ void test_vst1_lane_p8(poly8_t *a, poly8x8_t b) {
vst1_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst1_lane_p16(i16* %a, <4 x i16> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_p16(i16* %a, <4 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i16* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <4 x i16> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
@@ -4392,7 +4392,7 @@ void test_vst1_lane_p16(poly16_t *a, poly16x4_t b) {
vst1_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst1_lane_p64(i64* %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define void @test_vst1_lane_p64(i64* %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %a to i8*
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
@@ -4404,7 +4404,7 @@ void test_vst1_lane_p64(poly64_t *a, poly64x1_t b) {
vst1_lane_p64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst2q_lane_u8(i8* %a, [2 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_u8(i8* %a, [2 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[B]], i32 0, i32 0
@@ -4424,7 +4424,7 @@ void test_vst2q_lane_u8(uint8_t *a, uint8x16x2_t b) {
vst2q_lane_u8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst2q_lane_u16(i16* %a, [2 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_u16(i16* %a, [2 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x8x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint16x8x2_t, %struct.uint16x8x2_t* [[B]], i32 0, i32 0
@@ -4449,7 +4449,7 @@ void test_vst2q_lane_u16(uint16_t *a, uint16x8x2_t b) {
vst2q_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2q_lane_u32(i32* %a, [2 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_u32(i32* %a, [2 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint32x4x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x4x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint32x4x2_t, %struct.uint32x4x2_t* [[B]], i32 0, i32 0
@@ -4474,7 +4474,7 @@ void test_vst2q_lane_u32(uint32_t *a, uint32x4x2_t b) {
vst2q_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2q_lane_u64(i64* %a, [2 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_u64(i64* %a, [2 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x2x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint64x2x2_t, %struct.uint64x2x2_t* [[B]], i32 0, i32 0
@@ -4499,7 +4499,7 @@ void test_vst2q_lane_u64(uint64_t *a, uint64x2x2_t b) {
vst2q_lane_u64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2q_lane_s8(i8* %a, [2 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_s8(i8* %a, [2 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[B]], i32 0, i32 0
@@ -4519,7 +4519,7 @@ void test_vst2q_lane_s8(int8_t *a, int8x16x2_t b) {
vst2q_lane_s8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst2q_lane_s16(i16* %a, [2 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_s16(i16* %a, [2 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int16x8x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int16x8x2_t, %struct.int16x8x2_t* [[B]], i32 0, i32 0
@@ -4544,7 +4544,7 @@ void test_vst2q_lane_s16(int16_t *a, int16x8x2_t b) {
vst2q_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2q_lane_s32(i32* %a, [2 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_s32(i32* %a, [2 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int32x4x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int32x4x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int32x4x2_t, %struct.int32x4x2_t* [[B]], i32 0, i32 0
@@ -4569,7 +4569,7 @@ void test_vst2q_lane_s32(int32_t *a, int32x4x2_t b) {
vst2q_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2q_lane_s64(i64* %a, [2 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_s64(i64* %a, [2 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int64x2x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int64x2x2_t, %struct.int64x2x2_t* [[B]], i32 0, i32 0
@@ -4594,7 +4594,7 @@ void test_vst2q_lane_s64(int64_t *a, int64x2x2_t b) {
vst2q_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2q_lane_f16(half* %a, [2 x <8 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_f16(half* %a, [2 x <8 x half>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float16x8x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float16x8x2_t, %struct.float16x8x2_t* [[B]], i32 0, i32 0
@@ -4619,7 +4619,7 @@ void test_vst2q_lane_f16(float16_t *a, float16x8x2_t b) {
vst2q_lane_f16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2q_lane_f32(float* %a, [2 x <4 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_f32(float* %a, [2 x <4 x float>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float32x4x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float32x4x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float32x4x2_t, %struct.float32x4x2_t* [[B]], i32 0, i32 0
@@ -4644,7 +4644,7 @@ void test_vst2q_lane_f32(float32_t *a, float32x4x2_t b) {
vst2q_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2q_lane_f64(double* %a, [2 x <2 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_f64(double* %a, [2 x <2 x double>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float64x2x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float64x2x2_t, %struct.float64x2x2_t* [[B]], i32 0, i32 0
@@ -4669,7 +4669,7 @@ void test_vst2q_lane_f64(float64_t *a, float64x2x2_t b) {
vst2q_lane_f64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2q_lane_p8(i8* %a, [2 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_p8(i8* %a, [2 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[B]], i32 0, i32 0
@@ -4689,7 +4689,7 @@ void test_vst2q_lane_p8(poly8_t *a, poly8x16x2_t b) {
vst2q_lane_p8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst2q_lane_p16(i16* %a, [2 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_p16(i16* %a, [2 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly16x8x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x8x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly16x8x2_t, %struct.poly16x8x2_t* [[B]], i32 0, i32 0
@@ -4714,7 +4714,7 @@ void test_vst2q_lane_p16(poly16_t *a, poly16x8x2_t b) {
vst2q_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2q_lane_p64(i64* %a, [2 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_lane_p64(i64* %a, [2 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x2x2_t, %struct.poly64x2x2_t* [[B]], i32 0, i32 0
@@ -4739,7 +4739,7 @@ void test_vst2q_lane_p64(poly64_t *a, poly64x2x2_t b) {
vst2q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2_lane_u8(i8* %a, [2 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_u8(i8* %a, [2 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint8x8x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x8x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x8x2_t, %struct.uint8x8x2_t* [[B]], i32 0, i32 0
@@ -4759,7 +4759,7 @@ void test_vst2_lane_u8(uint8_t *a, uint8x8x2_t b) {
vst2_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2_lane_u16(i16* %a, [2 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_u16(i16* %a, [2 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x4x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint16x4x2_t, %struct.uint16x4x2_t* [[B]], i32 0, i32 0
@@ -4784,7 +4784,7 @@ void test_vst2_lane_u16(uint16_t *a, uint16x4x2_t b) {
vst2_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2_lane_u32(i32* %a, [2 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_u32(i32* %a, [2 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint32x2x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x2x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint32x2x2_t, %struct.uint32x2x2_t* [[B]], i32 0, i32 0
@@ -4809,7 +4809,7 @@ void test_vst2_lane_u32(uint32_t *a, uint32x2x2_t b) {
vst2_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2_lane_u64(i64* %a, [2 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_u64(i64* %a, [2 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x1x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint64x1x2_t, %struct.uint64x1x2_t* [[B]], i32 0, i32 0
@@ -4834,7 +4834,7 @@ void test_vst2_lane_u64(uint64_t *a, uint64x1x2_t b) {
vst2_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst2_lane_s8(i8* %a, [2 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_s8(i8* %a, [2 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int8x8x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int8x8x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x8x2_t, %struct.int8x8x2_t* [[B]], i32 0, i32 0
@@ -4854,7 +4854,7 @@ void test_vst2_lane_s8(int8_t *a, int8x8x2_t b) {
vst2_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2_lane_s16(i16* %a, [2 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_s16(i16* %a, [2 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int16x4x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int16x4x2_t, %struct.int16x4x2_t* [[B]], i32 0, i32 0
@@ -4879,7 +4879,7 @@ void test_vst2_lane_s16(int16_t *a, int16x4x2_t b) {
vst2_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2_lane_s32(i32* %a, [2 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_s32(i32* %a, [2 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int32x2x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int32x2x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int32x2x2_t, %struct.int32x2x2_t* [[B]], i32 0, i32 0
@@ -4904,7 +4904,7 @@ void test_vst2_lane_s32(int32_t *a, int32x2x2_t b) {
vst2_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2_lane_s64(i64* %a, [2 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_s64(i64* %a, [2 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int64x1x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int64x1x2_t, %struct.int64x1x2_t* [[B]], i32 0, i32 0
@@ -4929,7 +4929,7 @@ void test_vst2_lane_s64(int64_t *a, int64x1x2_t b) {
vst2_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst2_lane_f16(half* %a, [2 x <4 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_f16(half* %a, [2 x <4 x half>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float16x4x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float16x4x2_t, %struct.float16x4x2_t* [[B]], i32 0, i32 0
@@ -4954,7 +4954,7 @@ void test_vst2_lane_f16(float16_t *a, float16x4x2_t b) {
vst2_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2_lane_f32(float* %a, [2 x <2 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_f32(float* %a, [2 x <2 x float>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float32x2x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float32x2x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float32x2x2_t, %struct.float32x2x2_t* [[B]], i32 0, i32 0
@@ -4979,7 +4979,7 @@ void test_vst2_lane_f32(float32_t *a, float32x2x2_t b) {
vst2_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst2_lane_f64(double* %a, [2 x <1 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_f64(double* %a, [2 x <1 x double>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float64x1x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float64x1x2_t, %struct.float64x1x2_t* [[B]], i32 0, i32 0
@@ -5004,7 +5004,7 @@ void test_vst2_lane_f64(float64_t *a, float64x1x2_t b) {
vst2_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst2_lane_p8(i8* %a, [2 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_p8(i8* %a, [2 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly8x8x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x8x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x8x2_t, %struct.poly8x8x2_t* [[B]], i32 0, i32 0
@@ -5024,7 +5024,7 @@ void test_vst2_lane_p8(poly8_t *a, poly8x8x2_t b) {
vst2_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst2_lane_p16(i16* %a, [2 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_p16(i16* %a, [2 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly16x4x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x4x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly16x4x2_t, %struct.poly16x4x2_t* [[B]], i32 0, i32 0
@@ -5049,7 +5049,7 @@ void test_vst2_lane_p16(poly16_t *a, poly16x4x2_t b) {
vst2_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst2_lane_p64(i64* %a, [2 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_lane_p64(i64* %a, [2 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x1x2_t, %struct.poly64x1x2_t* [[B]], i32 0, i32 0
@@ -5074,7 +5074,7 @@ void test_vst2_lane_p64(poly64_t *a, poly64x1x2_t b) {
vst2_lane_p64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst3q_lane_u8(i8* %a, [3 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_u8(i8* %a, [3 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[B]], i32 0, i32 0
@@ -5097,7 +5097,7 @@ void test_vst3q_lane_u8(uint8_t *a, uint8x16x3_t b) {
vst3q_lane_u8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst3q_lane_u16(i16* %a, [3 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_u16(i16* %a, [3 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x8x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint16x8x3_t, %struct.uint16x8x3_t* [[B]], i32 0, i32 0
@@ -5127,7 +5127,7 @@ void test_vst3q_lane_u16(uint16_t *a, uint16x8x3_t b) {
vst3q_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3q_lane_u32(i32* %a, [3 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_u32(i32* %a, [3 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint32x4x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x4x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint32x4x3_t, %struct.uint32x4x3_t* [[B]], i32 0, i32 0
@@ -5157,7 +5157,7 @@ void test_vst3q_lane_u32(uint32_t *a, uint32x4x3_t b) {
vst3q_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3q_lane_u64(i64* %a, [3 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_u64(i64* %a, [3 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x2x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint64x2x3_t, %struct.uint64x2x3_t* [[B]], i32 0, i32 0
@@ -5187,7 +5187,7 @@ void test_vst3q_lane_u64(uint64_t *a, uint64x2x3_t b) {
vst3q_lane_u64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3q_lane_s8(i8* %a, [3 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_s8(i8* %a, [3 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[B]], i32 0, i32 0
@@ -5210,7 +5210,7 @@ void test_vst3q_lane_s8(int8_t *a, int8x16x3_t b) {
vst3q_lane_s8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst3q_lane_s16(i16* %a, [3 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_s16(i16* %a, [3 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int16x8x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int16x8x3_t, %struct.int16x8x3_t* [[B]], i32 0, i32 0
@@ -5240,7 +5240,7 @@ void test_vst3q_lane_s16(int16_t *a, int16x8x3_t b) {
vst3q_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3q_lane_s32(i32* %a, [3 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_s32(i32* %a, [3 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int32x4x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int32x4x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int32x4x3_t, %struct.int32x4x3_t* [[B]], i32 0, i32 0
@@ -5270,7 +5270,7 @@ void test_vst3q_lane_s32(int32_t *a, int32x4x3_t b) {
vst3q_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3q_lane_s64(i64* %a, [3 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_s64(i64* %a, [3 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int64x2x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int64x2x3_t, %struct.int64x2x3_t* [[B]], i32 0, i32 0
@@ -5300,7 +5300,7 @@ void test_vst3q_lane_s64(int64_t *a, int64x2x3_t b) {
vst3q_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3q_lane_f16(half* %a, [3 x <8 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_f16(half* %a, [3 x <8 x half>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float16x8x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float16x8x3_t, %struct.float16x8x3_t* [[B]], i32 0, i32 0
@@ -5330,7 +5330,7 @@ void test_vst3q_lane_f16(float16_t *a, float16x8x3_t b) {
vst3q_lane_f16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3q_lane_f32(float* %a, [3 x <4 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_f32(float* %a, [3 x <4 x float>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float32x4x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float32x4x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float32x4x3_t, %struct.float32x4x3_t* [[B]], i32 0, i32 0
@@ -5360,7 +5360,7 @@ void test_vst3q_lane_f32(float32_t *a, float32x4x3_t b) {
vst3q_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3q_lane_f64(double* %a, [3 x <2 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_f64(double* %a, [3 x <2 x double>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float64x2x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float64x2x3_t, %struct.float64x2x3_t* [[B]], i32 0, i32 0
@@ -5390,7 +5390,7 @@ void test_vst3q_lane_f64(float64_t *a, float64x2x3_t b) {
vst3q_lane_f64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3q_lane_p8(i8* %a, [3 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_p8(i8* %a, [3 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[B]], i32 0, i32 0
@@ -5413,7 +5413,7 @@ void test_vst3q_lane_p8(poly8_t *a, poly8x16x3_t b) {
vst3q_lane_p8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst3q_lane_p16(i16* %a, [3 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_p16(i16* %a, [3 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly16x8x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x8x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly16x8x3_t, %struct.poly16x8x3_t* [[B]], i32 0, i32 0
@@ -5443,7 +5443,7 @@ void test_vst3q_lane_p16(poly16_t *a, poly16x8x3_t b) {
vst3q_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3q_lane_p64(i64* %a, [3 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_lane_p64(i64* %a, [3 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x2x3_t, %struct.poly64x2x3_t* [[B]], i32 0, i32 0
@@ -5473,7 +5473,7 @@ void test_vst3q_lane_p64(poly64_t *a, poly64x2x3_t b) {
vst3q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3_lane_u8(i8* %a, [3 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_u8(i8* %a, [3 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint8x8x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x8x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x8x3_t, %struct.uint8x8x3_t* [[B]], i32 0, i32 0
@@ -5496,7 +5496,7 @@ void test_vst3_lane_u8(uint8_t *a, uint8x8x3_t b) {
vst3_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3_lane_u16(i16* %a, [3 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_u16(i16* %a, [3 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x4x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint16x4x3_t, %struct.uint16x4x3_t* [[B]], i32 0, i32 0
@@ -5526,7 +5526,7 @@ void test_vst3_lane_u16(uint16_t *a, uint16x4x3_t b) {
vst3_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3_lane_u32(i32* %a, [3 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_u32(i32* %a, [3 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint32x2x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x2x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint32x2x3_t, %struct.uint32x2x3_t* [[B]], i32 0, i32 0
@@ -5556,7 +5556,7 @@ void test_vst3_lane_u32(uint32_t *a, uint32x2x3_t b) {
vst3_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3_lane_u64(i64* %a, [3 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_u64(i64* %a, [3 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x1x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint64x1x3_t, %struct.uint64x1x3_t* [[B]], i32 0, i32 0
@@ -5586,7 +5586,7 @@ void test_vst3_lane_u64(uint64_t *a, uint64x1x3_t b) {
vst3_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst3_lane_s8(i8* %a, [3 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_s8(i8* %a, [3 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int8x8x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int8x8x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x8x3_t, %struct.int8x8x3_t* [[B]], i32 0, i32 0
@@ -5609,7 +5609,7 @@ void test_vst3_lane_s8(int8_t *a, int8x8x3_t b) {
vst3_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3_lane_s16(i16* %a, [3 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_s16(i16* %a, [3 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int16x4x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int16x4x3_t, %struct.int16x4x3_t* [[B]], i32 0, i32 0
@@ -5639,7 +5639,7 @@ void test_vst3_lane_s16(int16_t *a, int16x4x3_t b) {
vst3_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3_lane_s32(i32* %a, [3 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_s32(i32* %a, [3 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int32x2x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int32x2x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int32x2x3_t, %struct.int32x2x3_t* [[B]], i32 0, i32 0
@@ -5669,7 +5669,7 @@ void test_vst3_lane_s32(int32_t *a, int32x2x3_t b) {
vst3_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3_lane_s64(i64* %a, [3 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_s64(i64* %a, [3 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int64x1x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int64x1x3_t, %struct.int64x1x3_t* [[B]], i32 0, i32 0
@@ -5699,7 +5699,7 @@ void test_vst3_lane_s64(int64_t *a, int64x1x3_t b) {
vst3_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst3_lane_f16(half* %a, [3 x <4 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_f16(half* %a, [3 x <4 x half>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float16x4x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float16x4x3_t, %struct.float16x4x3_t* [[B]], i32 0, i32 0
@@ -5729,7 +5729,7 @@ void test_vst3_lane_f16(float16_t *a, float16x4x3_t b) {
vst3_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3_lane_f32(float* %a, [3 x <2 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_f32(float* %a, [3 x <2 x float>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float32x2x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float32x2x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float32x2x3_t, %struct.float32x2x3_t* [[B]], i32 0, i32 0
@@ -5759,7 +5759,7 @@ void test_vst3_lane_f32(float32_t *a, float32x2x3_t b) {
vst3_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst3_lane_f64(double* %a, [3 x <1 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_f64(double* %a, [3 x <1 x double>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float64x1x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float64x1x3_t, %struct.float64x1x3_t* [[B]], i32 0, i32 0
@@ -5789,7 +5789,7 @@ void test_vst3_lane_f64(float64_t *a, float64x1x3_t b) {
vst3_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst3_lane_p8(i8* %a, [3 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_p8(i8* %a, [3 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly8x8x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x8x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x8x3_t, %struct.poly8x8x3_t* [[B]], i32 0, i32 0
@@ -5812,7 +5812,7 @@ void test_vst3_lane_p8(poly8_t *a, poly8x8x3_t b) {
vst3_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst3_lane_p16(i16* %a, [3 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_p16(i16* %a, [3 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly16x4x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x4x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly16x4x3_t, %struct.poly16x4x3_t* [[B]], i32 0, i32 0
@@ -5842,7 +5842,7 @@ void test_vst3_lane_p16(poly16_t *a, poly16x4x3_t b) {
vst3_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst3_lane_p64(i64* %a, [3 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_lane_p64(i64* %a, [3 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x1x3_t, %struct.poly64x1x3_t* [[B]], i32 0, i32 0
@@ -5872,7 +5872,7 @@ void test_vst3_lane_p64(poly64_t *a, poly64x1x3_t b) {
vst3_lane_p64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst4q_lane_u8(i8* %a, [4 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_u8(i8* %a, [4 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[B]], i32 0, i32 0
@@ -5898,7 +5898,7 @@ void test_vst4q_lane_u8(uint8_t *a, uint8x16x4_t b) {
vst4q_lane_u8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst4q_lane_u16(i16* %a, [4 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_u16(i16* %a, [4 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x8x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint16x8x4_t, %struct.uint16x8x4_t* [[B]], i32 0, i32 0
@@ -5933,7 +5933,7 @@ void test_vst4q_lane_u16(uint16_t *a, uint16x8x4_t b) {
vst4q_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4q_lane_u32(i32* %a, [4 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_u32(i32* %a, [4 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint32x4x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x4x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint32x4x4_t, %struct.uint32x4x4_t* [[B]], i32 0, i32 0
@@ -5968,7 +5968,7 @@ void test_vst4q_lane_u32(uint32_t *a, uint32x4x4_t b) {
vst4q_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4q_lane_u64(i64* %a, [4 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_u64(i64* %a, [4 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x2x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint64x2x4_t, %struct.uint64x2x4_t* [[B]], i32 0, i32 0
@@ -6003,7 +6003,7 @@ void test_vst4q_lane_u64(uint64_t *a, uint64x2x4_t b) {
vst4q_lane_u64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4q_lane_s8(i8* %a, [4 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_s8(i8* %a, [4 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[B]], i32 0, i32 0
@@ -6029,7 +6029,7 @@ void test_vst4q_lane_s8(int8_t *a, int8x16x4_t b) {
vst4q_lane_s8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst4q_lane_s16(i16* %a, [4 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_s16(i16* %a, [4 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int16x8x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int16x8x4_t, %struct.int16x8x4_t* [[B]], i32 0, i32 0
@@ -6064,7 +6064,7 @@ void test_vst4q_lane_s16(int16_t *a, int16x8x4_t b) {
vst4q_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4q_lane_s32(i32* %a, [4 x <4 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_s32(i32* %a, [4 x <4 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int32x4x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int32x4x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int32x4x4_t, %struct.int32x4x4_t* [[B]], i32 0, i32 0
@@ -6099,7 +6099,7 @@ void test_vst4q_lane_s32(int32_t *a, int32x4x4_t b) {
vst4q_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4q_lane_s64(i64* %a, [4 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_s64(i64* %a, [4 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.int64x2x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int64x2x4_t, %struct.int64x2x4_t* [[B]], i32 0, i32 0
@@ -6134,7 +6134,7 @@ void test_vst4q_lane_s64(int64_t *a, int64x2x4_t b) {
vst4q_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4q_lane_f16(half* %a, [4 x <8 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_f16(half* %a, [4 x <8 x half>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float16x8x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float16x8x4_t, %struct.float16x8x4_t* [[B]], i32 0, i32 0
@@ -6169,7 +6169,7 @@ void test_vst4q_lane_f16(float16_t *a, float16x8x4_t b) {
vst4q_lane_f16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4q_lane_f32(float* %a, [4 x <4 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_f32(float* %a, [4 x <4 x float>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float32x4x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float32x4x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float32x4x4_t, %struct.float32x4x4_t* [[B]], i32 0, i32 0
@@ -6204,7 +6204,7 @@ void test_vst4q_lane_f32(float32_t *a, float32x4x4_t b) {
vst4q_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4q_lane_f64(double* %a, [4 x <2 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_f64(double* %a, [4 x <2 x double>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.float64x2x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float64x2x4_t, %struct.float64x2x4_t* [[B]], i32 0, i32 0
@@ -6239,7 +6239,7 @@ void test_vst4q_lane_f64(float64_t *a, float64x2x4_t b) {
vst4q_lane_f64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4q_lane_p8(i8* %a, [4 x <16 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_p8(i8* %a, [4 x <16 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[B]], i32 0, i32 0
@@ -6265,7 +6265,7 @@ void test_vst4q_lane_p8(poly8_t *a, poly8x16x4_t b) {
vst4q_lane_p8(a, b, 15);
}
-// CHECK-LABEL: define void @test_vst4q_lane_p16(i16* %a, [4 x <8 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_p16(i16* %a, [4 x <8 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly16x8x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x8x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly16x8x4_t, %struct.poly16x8x4_t* [[B]], i32 0, i32 0
@@ -6300,7 +6300,7 @@ void test_vst4q_lane_p16(poly16_t *a, poly16x8x4_t b) {
vst4q_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4q_lane_p64(i64* %a, [4 x <2 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_lane_p64(i64* %a, [4 x <2 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x2x4_t, %struct.poly64x2x4_t* [[B]], i32 0, i32 0
@@ -6335,7 +6335,7 @@ void test_vst4q_lane_p64(poly64_t *a, poly64x2x4_t b) {
vst4q_lane_p64(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4_lane_u8(i8* %a, [4 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_u8(i8* %a, [4 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint8x8x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint8x8x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x8x4_t, %struct.uint8x8x4_t* [[B]], i32 0, i32 0
@@ -6361,7 +6361,7 @@ void test_vst4_lane_u8(uint8_t *a, uint8x8x4_t b) {
vst4_lane_u8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4_lane_u16(i16* %a, [4 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_u16(i16* %a, [4 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint16x4x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint16x4x4_t, %struct.uint16x4x4_t* [[B]], i32 0, i32 0
@@ -6396,7 +6396,7 @@ void test_vst4_lane_u16(uint16_t *a, uint16x4x4_t b) {
vst4_lane_u16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4_lane_u32(i32* %a, [4 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_u32(i32* %a, [4 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint32x2x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint32x2x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint32x2x4_t, %struct.uint32x2x4_t* [[B]], i32 0, i32 0
@@ -6431,7 +6431,7 @@ void test_vst4_lane_u32(uint32_t *a, uint32x2x4_t b) {
vst4_lane_u32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4_lane_u64(i64* %a, [4 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_u64(i64* %a, [4 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.uint64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.uint64x1x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint64x1x4_t, %struct.uint64x1x4_t* [[B]], i32 0, i32 0
@@ -6466,7 +6466,7 @@ void test_vst4_lane_u64(uint64_t *a, uint64x1x4_t b) {
vst4_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst4_lane_s8(i8* %a, [4 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_s8(i8* %a, [4 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int8x8x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int8x8x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x8x4_t, %struct.int8x8x4_t* [[B]], i32 0, i32 0
@@ -6492,7 +6492,7 @@ void test_vst4_lane_s8(int8_t *a, int8x8x4_t b) {
vst4_lane_s8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4_lane_s16(i16* %a, [4 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_s16(i16* %a, [4 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int16x4x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int16x4x4_t, %struct.int16x4x4_t* [[B]], i32 0, i32 0
@@ -6527,7 +6527,7 @@ void test_vst4_lane_s16(int16_t *a, int16x4x4_t b) {
vst4_lane_s16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4_lane_s32(i32* %a, [4 x <2 x i32>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_s32(i32* %a, [4 x <2 x i32>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int32x2x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int32x2x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int32x2x4_t, %struct.int32x2x4_t* [[B]], i32 0, i32 0
@@ -6562,7 +6562,7 @@ void test_vst4_lane_s32(int32_t *a, int32x2x4_t b) {
vst4_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4_lane_s64(i64* %a, [4 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_s64(i64* %a, [4 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.int64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.int64x1x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int64x1x4_t, %struct.int64x1x4_t* [[B]], i32 0, i32 0
@@ -6597,7 +6597,7 @@ void test_vst4_lane_s64(int64_t *a, int64x1x4_t b) {
vst4_lane_s64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst4_lane_f16(half* %a, [4 x <4 x half>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_f16(half* %a, [4 x <4 x half>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float16x4x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float16x4x4_t, %struct.float16x4x4_t* [[B]], i32 0, i32 0
@@ -6632,7 +6632,7 @@ void test_vst4_lane_f16(float16_t *a, float16x4x4_t b) {
vst4_lane_f16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4_lane_f32(float* %a, [4 x <2 x float>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_f32(float* %a, [4 x <2 x float>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float32x2x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float32x2x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float32x2x4_t, %struct.float32x2x4_t* [[B]], i32 0, i32 0
@@ -6667,7 +6667,7 @@ void test_vst4_lane_f32(float32_t *a, float32x2x4_t b) {
vst4_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define void @test_vst4_lane_f64(double* %a, [4 x <1 x double>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_f64(double* %a, [4 x <1 x double>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.float64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.float64x1x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.float64x1x4_t, %struct.float64x1x4_t* [[B]], i32 0, i32 0
@@ -6702,7 +6702,7 @@ void test_vst4_lane_f64(float64_t *a, float64x1x4_t b) {
vst4_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define void @test_vst4_lane_p8(i8* %a, [4 x <8 x i8>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_p8(i8* %a, [4 x <8 x i8>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly8x8x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly8x8x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x8x4_t, %struct.poly8x8x4_t* [[B]], i32 0, i32 0
@@ -6728,7 +6728,7 @@ void test_vst4_lane_p8(poly8_t *a, poly8x8x4_t b) {
vst4_lane_p8(a, b, 7);
}
-// CHECK-LABEL: define void @test_vst4_lane_p16(i16* %a, [4 x <4 x i16>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_p16(i16* %a, [4 x <4 x i16>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly16x4x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly16x4x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly16x4x4_t, %struct.poly16x4x4_t* [[B]], i32 0, i32 0
@@ -6763,7 +6763,7 @@ void test_vst4_lane_p16(poly16_t *a, poly16x4x4_t b) {
vst4_lane_p16(a, b, 3);
}
-// CHECK-LABEL: define void @test_vst4_lane_p64(i64* %a, [4 x <1 x i64>] %b.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_lane_p64(i64* %a, [4 x <1 x i64>] %b.coerce) #2 {
// CHECK: [[B:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x1x4_t, %struct.poly64x1x4_t* [[B]], i32 0, i32 0
@@ -6797,3 +6797,7 @@ void test_vst4_lane_p16(poly16_t *a, poly16x4x4_t b) {
void test_vst4_lane_p64(poly64_t *a, poly64x1x4_t b) {
vst4_lane_p64(a, b, 0);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="128"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #2 ={{.*}}"min-legal-vector-width"="0"
diff --git a/test/CodeGen/aarch64-neon-scalar-copy.c b/test/CodeGen/aarch64-neon-scalar-copy.c
index 28cff5fbf3..d7daf82998 100644
--- a/test/CodeGen/aarch64-neon-scalar-copy.c
+++ b/test/CodeGen/aarch64-neon-scalar-copy.c
@@ -23,7 +23,7 @@ float64_t test_vdupd_lane_f64(float64x1_t a) {
}
-// CHECK-LABEL: define float @test_vdups_laneq_f32(<4 x float> %a) #0 {
+// CHECK-LABEL: define float @test_vdups_laneq_f32(<4 x float> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x float> [[TMP1]], i32 3
@@ -33,7 +33,7 @@ float32_t test_vdups_laneq_f32(float32x4_t a) {
}
-// CHECK-LABEL: define double @test_vdupd_laneq_f64(<2 x double> %a) #0 {
+// CHECK-LABEL: define double @test_vdupd_laneq_f64(<2 x double> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x double>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x double> [[TMP1]], i32 1
@@ -118,7 +118,7 @@ uint64_t test_vdupd_lane_u64(uint64x1_t a) {
return vdupd_lane_u64(a, 0);
}
-// CHECK-LABEL: define i8 @test_vdupb_laneq_s8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i8 @test_vdupb_laneq_s8(<16 x i8> %a) #1 {
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <16 x i8> %a, i32 15
// CHECK: ret i8 [[VGETQ_LANE]]
int8_t test_vdupb_laneq_s8(int8x16_t a) {
@@ -126,7 +126,7 @@ int8_t test_vdupb_laneq_s8(int8x16_t a) {
}
-// CHECK-LABEL: define i16 @test_vduph_laneq_s16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i16 @test_vduph_laneq_s16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -136,7 +136,7 @@ int16_t test_vduph_laneq_s16(int16x8_t a) {
}
-// CHECK-LABEL: define i32 @test_vdups_laneq_s32(<4 x i32> %a) #0 {
+// CHECK-LABEL: define i32 @test_vdups_laneq_s32(<4 x i32> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -146,7 +146,7 @@ int32_t test_vdups_laneq_s32(int32x4_t a) {
}
-// CHECK-LABEL: define i64 @test_vdupd_laneq_s64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i64 @test_vdupd_laneq_s64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
@@ -156,7 +156,7 @@ int64_t test_vdupd_laneq_s64(int64x2_t a) {
}
-// CHECK-LABEL: define i8 @test_vdupb_laneq_u8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i8 @test_vdupb_laneq_u8(<16 x i8> %a) #1 {
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <16 x i8> %a, i32 15
// CHECK: ret i8 [[VGETQ_LANE]]
uint8_t test_vdupb_laneq_u8(uint8x16_t a) {
@@ -164,7 +164,7 @@ uint8_t test_vdupb_laneq_u8(uint8x16_t a) {
}
-// CHECK-LABEL: define i16 @test_vduph_laneq_u16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i16 @test_vduph_laneq_u16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -174,7 +174,7 @@ uint16_t test_vduph_laneq_u16(uint16x8_t a) {
}
-// CHECK-LABEL: define i32 @test_vdups_laneq_u32(<4 x i32> %a) #0 {
+// CHECK-LABEL: define i32 @test_vdups_laneq_u32(<4 x i32> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -184,7 +184,7 @@ uint32_t test_vdups_laneq_u32(uint32x4_t a) {
}
-// CHECK-LABEL: define i64 @test_vdupd_laneq_u64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i64 @test_vdupd_laneq_u64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
@@ -209,14 +209,14 @@ poly16_t test_vduph_lane_p16(poly16x4_t a) {
return vduph_lane_p16(a, 3);
}
-// CHECK-LABEL: define i8 @test_vdupb_laneq_p8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i8 @test_vdupb_laneq_p8(<16 x i8> %a) #1 {
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <16 x i8> %a, i32 15
// CHECK: ret i8 [[VGETQ_LANE]]
poly8_t test_vdupb_laneq_p8(poly8x16_t a) {
return vdupb_laneq_p8(a, 15);
}
-// CHECK-LABEL: define i16 @test_vduph_laneq_p16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i16 @test_vduph_laneq_p16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -225,3 +225,5 @@ poly16_t test_vduph_laneq_p16(poly16x8_t a) {
return vduph_laneq_p16(a, 7);
}
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c b/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
index e85b918d5a..88ab0c50ba 100644
--- a/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
+++ b/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
@@ -26,7 +26,7 @@ float64_t test_vmuld_lane_f64(float64_t a, float64x1_t b) {
return vmuld_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define float @test_vmuls_laneq_f32(float %a, <4 x float> %b) #0 {
+// CHECK-LABEL: define float @test_vmuls_laneq_f32(float %a, <4 x float> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x float> [[TMP1]], i32 3
@@ -36,7 +36,7 @@ float32_t test_vmuls_laneq_f32(float32_t a, float32x4_t b) {
return vmuls_laneq_f32(a, b, 3);
}
-// CHECK-LABEL: define double @test_vmuld_laneq_f64(double %a, <2 x double> %b) #0 {
+// CHECK-LABEL: define double @test_vmuld_laneq_f64(double %a, <2 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x double>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x double> [[TMP1]], i32 1
@@ -65,7 +65,7 @@ float32_t test_vmulxs_lane_f32(float32_t a, float32x2_t b) {
return vmulxs_lane_f32(a, b, 1);
}
-// CHECK-LABEL: define float @test_vmulxs_laneq_f32(float %a, <4 x float> %b) #0 {
+// CHECK-LABEL: define float @test_vmulxs_laneq_f32(float %a, <4 x float> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x float> [[TMP1]], i32 3
@@ -85,7 +85,7 @@ float64_t test_vmulxd_lane_f64(float64_t a, float64x1_t b) {
return vmulxd_lane_f64(a, b, 0);
}
-// CHECK-LABEL: define double @test_vmulxd_laneq_f64(double %a, <2 x double> %b) #0 {
+// CHECK-LABEL: define double @test_vmulxd_laneq_f64(double %a, <2 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x double>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x double> [[TMP1]], i32 1
@@ -112,7 +112,7 @@ float64x1_t test_vmulx_lane_f64(float64x1_t a, float64x1_t b) {
}
-// CHECK-LABEL: define <1 x double> @test_vmulx_laneq_f64_0(<1 x double> %a, <2 x double> %b) #0 {
+// CHECK-LABEL: define <1 x double> @test_vmulx_laneq_f64_0(<1 x double> %a, <2 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <1 x double> %a to <8 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x double>
// CHECK: [[VGET_LANE:%.*]] = extractelement <1 x double> [[TMP1]], i32 0
@@ -128,7 +128,7 @@ float64x1_t test_vmulx_laneq_f64_0(float64x1_t a, float64x2_t b) {
return vmulx_laneq_f64(a, b, 0);
}
-// CHECK-LABEL: define <1 x double> @test_vmulx_laneq_f64_1(<1 x double> %a, <2 x double> %b) #0 {
+// CHECK-LABEL: define <1 x double> @test_vmulx_laneq_f64_1(<1 x double> %a, <2 x double> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <1 x double> %a to <8 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x double>
// CHECK: [[VGET_LANE:%.*]] = extractelement <1 x double> [[TMP1]], i32 0
@@ -165,7 +165,7 @@ float64_t test_vfmad_lane_f64(float64_t a, float64_t b, float64x1_t c) {
return vfmad_lane_f64(a, b, c, 0);
}
-// CHECK-LABEL: define double @test_vfmad_laneq_f64(double %a, double %b, <2 x double> %c) #0 {
+// CHECK-LABEL: define double @test_vfmad_laneq_f64(double %a, double %b, <2 x double> %c) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %c to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x double>
// CHECK: [[EXTRACT:%.*]] = extractelement <2 x double> [[TMP1]], i32 1
@@ -215,7 +215,7 @@ float64x1_t test_vfms_lane_f64(float64x1_t a, float64x1_t b, float64x1_t v) {
return vfms_lane_f64(a, b, v, 0);
}
-// CHECK-LABEL: define <1 x double> @test_vfma_laneq_f64(<1 x double> %a, <1 x double> %b, <2 x double> %v) #0 {
+// CHECK-LABEL: define <1 x double> @test_vfma_laneq_f64(<1 x double> %a, <1 x double> %b, <2 x double> %v) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <1 x double> %a to <8 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <1 x double> %b to <8 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <2 x double> %v to <16 x i8>
@@ -230,7 +230,7 @@ float64x1_t test_vfma_laneq_f64(float64x1_t a, float64x1_t b, float64x2_t v) {
return vfma_laneq_f64(a, b, v, 0);
}
-// CHECK-LABEL: define <1 x double> @test_vfms_laneq_f64(<1 x double> %a, <1 x double> %b, <2 x double> %v) #0 {
+// CHECK-LABEL: define <1 x double> @test_vfms_laneq_f64(<1 x double> %a, <1 x double> %b, <2 x double> %v) #1 {
// CHECK: [[SUB:%.*]] = fsub <1 x double> <double -0.000000e+00>, %b
// CHECK: [[TMP0:%.*]] = bitcast <1 x double> %a to <8 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <1 x double> [[SUB]] to <8 x i8>
@@ -269,7 +269,7 @@ int64_t test_vqdmulls_lane_s32(int32_t a, int32x2_t b) {
return vqdmulls_lane_s32(a, b, 1);
}
-// CHECK-LABEL: define i32 @test_vqdmullh_laneq_s16(i16 %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define i32 @test_vqdmullh_laneq_s16(i16 %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -282,7 +282,7 @@ int32_t test_vqdmullh_laneq_s16(int16_t a, int16x8_t b) {
return vqdmullh_laneq_s16(a, b, 7);
}
-// CHECK-LABEL: define i64 @test_vqdmulls_laneq_s32(i32 %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define i64 @test_vqdmulls_laneq_s32(i32 %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -316,7 +316,7 @@ int32_t test_vqdmulhs_lane_s32(int32_t a, int32x2_t b) {
}
-// CHECK-LABEL: define i16 @test_vqdmulhh_laneq_s16(i16 %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define i16 @test_vqdmulhh_laneq_s16(i16 %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -330,7 +330,7 @@ int16_t test_vqdmulhh_laneq_s16(int16_t a, int16x8_t b) {
}
-// CHECK-LABEL: define i32 @test_vqdmulhs_laneq_s32(i32 %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define i32 @test_vqdmulhs_laneq_s32(i32 %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -364,7 +364,7 @@ int32_t test_vqrdmulhs_lane_s32(int32_t a, int32x2_t b) {
}
-// CHECK-LABEL: define i16 @test_vqrdmulhh_laneq_s16(i16 %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define i16 @test_vqrdmulhh_laneq_s16(i16 %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -378,7 +378,7 @@ int16_t test_vqrdmulhh_laneq_s16(int16_t a, int16x8_t b) {
}
-// CHECK-LABEL: define i32 @test_vqrdmulhs_laneq_s32(i32 %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define i32 @test_vqrdmulhs_laneq_s32(i32 %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -413,7 +413,7 @@ int64_t test_vqdmlals_lane_s32(int64_t a, int32_t b, int32x2_t c) {
return vqdmlals_lane_s32(a, b, c, 1);
}
-// CHECK-LABEL: define i32 @test_vqdmlalh_laneq_s16(i32 %a, i16 %b, <8 x i16> %c) #0 {
+// CHECK-LABEL: define i32 @test_vqdmlalh_laneq_s16(i32 %a, i16 %b, <8 x i16> %c) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %c to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -427,7 +427,7 @@ int32_t test_vqdmlalh_laneq_s16(int32_t a, int16_t b, int16x8_t c) {
return vqdmlalh_laneq_s16(a, b, c, 7);
}
-// CHECK-LABEL: define i64 @test_vqdmlals_laneq_s32(i64 %a, i32 %b, <4 x i32> %c) #0 {
+// CHECK-LABEL: define i64 @test_vqdmlals_laneq_s32(i64 %a, i32 %b, <4 x i32> %c) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %c to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -463,7 +463,7 @@ int64_t test_vqdmlsls_lane_s32(int64_t a, int32_t b, int32x2_t c) {
return vqdmlsls_lane_s32(a, b, c, 1);
}
-// CHECK-LABEL: define i32 @test_vqdmlslh_laneq_s16(i32 %a, i16 %b, <8 x i16> %c) #0 {
+// CHECK-LABEL: define i32 @test_vqdmlslh_laneq_s16(i32 %a, i16 %b, <8 x i16> %c) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %c to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -477,7 +477,7 @@ int32_t test_vqdmlslh_laneq_s16(int32_t a, int16_t b, int16x8_t c) {
return vqdmlslh_laneq_s16(a, b, c, 7);
}
-// CHECK-LABEL: define i64 @test_vqdmlsls_laneq_s32(i64 %a, i32 %b, <4 x i32> %c) #0 {
+// CHECK-LABEL: define i64 @test_vqdmlsls_laneq_s32(i64 %a, i32 %b, <4 x i32> %c) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %c to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -513,7 +513,7 @@ float64x1_t test_vmulx_lane_f64_0() {
return result;
}
-// CHECK-LABEL: define <1 x double> @test_vmulx_laneq_f64_2() #0 {
+// CHECK-LABEL: define <1 x double> @test_vmulx_laneq_f64_2() #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64 4599917171378402754 to <1 x double>
// CHECK: [[TMP1:%.*]] = bitcast i64 4606655882138939123 to <1 x double>
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <1 x double> [[TMP0]], <1 x double> [[TMP1]], <2 x i32> <i32 0, i32 1>
@@ -540,3 +540,6 @@ float64x1_t test_vmulx_laneq_f64_2() {
result = vmulx_laneq_f64(arg1, arg3, 1);
return result;
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-neon-tbl.c b/test/CodeGen/aarch64-neon-tbl.c
index 28881830bf..aa117facb7 100644
--- a/test/CodeGen/aarch64-neon-tbl.c
+++ b/test/CodeGen/aarch64-neon-tbl.c
@@ -7,14 +7,14 @@
// CHECK-LABEL: define <8 x i8> @test_vtbl1_s8(<8 x i8> %a, <8 x i8> %b) #0 {
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> %a, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL11_I]]
int8x8_t test_vtbl1_s8(int8x8_t a, int8x8_t b) {
return vtbl1_s8(a, b);
}
-// CHECK-LABEL: define <8 x i8> @test_vqtbl1_s8(<16 x i8> %a, <8 x i8> %b) #0 {
-// CHECK: [[VTBL1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> %a, <8 x i8> %b) #2
+// CHECK-LABEL: define <8 x i8> @test_vqtbl1_s8(<16 x i8> %a, <8 x i8> %b) #1 {
+// CHECK: [[VTBL1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> %a, <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL1_I]]
int8x8_t test_vqtbl1_s8(int8x16_t a, int8x8_t b) {
return vqtbl1_s8(a, b);
@@ -36,7 +36,7 @@ int8x8_t test_vqtbl1_s8(int8x16_t a, int8x8_t b) {
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <8 x i8>], [2 x <8 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX2_I]], align 8
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL13_I]]
int8x8_t test_vtbl2_s8(int8x8x2_t a, int8x8_t b) {
return vtbl2_s8(a, b);
@@ -57,7 +57,7 @@ int8x8_t test_vtbl2_s8(int8x8x2_t a, int8x8_t b) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBL2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %b) #2
+// CHECK: [[VTBL2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL2_I]]
int8x8_t test_vqtbl2_s8(int8x16x2_t a, int8x8_t b) {
return vqtbl2_s8(a, b);
@@ -83,7 +83,7 @@ int8x8_t test_vqtbl2_s8(int8x16x2_t a, int8x8_t b) {
// CHECK: [[TMP3:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX4_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL25_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL26_I]]
int8x8_t test_vtbl3_s8(int8x8x3_t a, int8x8_t b) {
return vtbl3_s8(a, b);
@@ -107,7 +107,7 @@ int8x8_t test_vtbl3_s8(int8x8x3_t a, int8x8_t b) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBL3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl3.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %b) #2
+// CHECK: [[VTBL3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl3.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL3_I]]
int8x8_t test_vqtbl3_s8(int8x16x3_t a, int8x8_t b) {
return vqtbl3_s8(a, b);
@@ -136,7 +136,7 @@ int8x8_t test_vqtbl3_s8(int8x16x3_t a, int8x8_t b) {
// CHECK: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX6_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL27_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL27_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL27_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL28_I]]
int8x8_t test_vtbl4_s8(int8x8x4_t a, int8x8_t b) {
return vtbl4_s8(a, b);
@@ -163,20 +163,20 @@ int8x8_t test_vtbl4_s8(int8x8x4_t a, int8x8_t b) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBL4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl4.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %b) #2
+// CHECK: [[VTBL4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl4.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL4_I]]
int8x8_t test_vqtbl4_s8(int8x16x4_t a, int8x8_t b) {
return vqtbl4_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl1q_s8(<16 x i8> %a, <16 x i8> %b) #0 {
-// CHECK: [[VTBL1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl1.v16i8(<16 x i8> %a, <16 x i8> %b) #2
+// CHECK-LABEL: define <16 x i8> @test_vqtbl1q_s8(<16 x i8> %a, <16 x i8> %b) #1 {
+// CHECK: [[VTBL1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl1.v16i8(<16 x i8> %a, <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL1_I]]
int8x16_t test_vqtbl1q_s8(int8x16_t a, int8x16_t b) {
return vqtbl1q_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl2q_s8([2 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl2q_s8([2 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[A]], i32 0, i32 0
@@ -191,13 +191,13 @@ int8x16_t test_vqtbl1q_s8(int8x16_t a, int8x16_t b) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBL2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %b) #2
+// CHECK: [[VTBL2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL2_I]]
int8x16_t test_vqtbl2q_s8(int8x16x2_t a, int8x16_t b) {
return vqtbl2q_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl3q_s8([3 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl3q_s8([3 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[A]], i32 0, i32 0
@@ -215,13 +215,13 @@ int8x16_t test_vqtbl2q_s8(int8x16x2_t a, int8x16_t b) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBL3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl3.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %b) #2
+// CHECK: [[VTBL3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl3.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL3_I]]
int8x16_t test_vqtbl3q_s8(int8x16x3_t a, int8x16_t b) {
return vqtbl3q_s8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl4q_s8([4 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl4q_s8([4 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[A]], i32 0, i32 0
@@ -242,7 +242,7 @@ int8x16_t test_vqtbl3q_s8(int8x16x3_t a, int8x16_t b) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBL4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl4.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %b) #2
+// CHECK: [[VTBL4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl4.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL4_I]]
int8x16_t test_vqtbl4q_s8(int8x16x4_t a, int8x16_t b) {
return vqtbl4q_s8(a, b);
@@ -250,7 +250,7 @@ int8x16_t test_vqtbl4q_s8(int8x16x4_t a, int8x16_t b) {
// CHECK-LABEL: define <8 x i8> @test_vtbx1_s8(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) #0 {
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> %b, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %c) #2
+// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %c) #3
// CHECK: [[TMP0:%.*]] = icmp uge <8 x i8> %c, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
// CHECK: [[TMP1:%.*]] = sext <8 x i1> [[TMP0]] to <8 x i8>
// CHECK: [[TMP2:%.*]] = and <8 x i8> [[TMP1]], %a
@@ -278,7 +278,7 @@ int8x8_t test_vtbx1_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <8 x i8>], [2 x <8 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX2_I]], align 8
// CHECK: [[VTBX1_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBX13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> [[VTBX1_I]], <8 x i8> %c) #2
+// CHECK: [[VTBX13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> [[VTBX1_I]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX13_I]]
int8x8_t test_vtbx2_s8(int8x8_t a, int8x8x2_t b, int8x8_t c) {
return vtbx2_s8(a, b, c);
@@ -304,7 +304,7 @@ int8x8_t test_vtbx2_s8(int8x8_t a, int8x8x2_t b, int8x8_t c) {
// CHECK: [[TMP3:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX4_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL25_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %c) #2
+// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %c) #3
// CHECK: [[TMP4:%.*]] = icmp uge <8 x i8> %c, <i8 24, i8 24, i8 24, i8 24, i8 24, i8 24, i8 24, i8 24>
// CHECK: [[TMP5:%.*]] = sext <8 x i1> [[TMP4]] to <8 x i8>
// CHECK: [[TMP6:%.*]] = and <8 x i8> [[TMP5]], %a
@@ -339,14 +339,14 @@ int8x8_t test_vtbx3_s8(int8x8_t a, int8x8x3_t b, int8x8_t c) {
// CHECK: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX6_I]], align 8
// CHECK: [[VTBX2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBX27_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBX28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[VTBX2_I]], <16 x i8> [[VTBX27_I]], <8 x i8> %c) #2
+// CHECK: [[VTBX28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[VTBX2_I]], <16 x i8> [[VTBX27_I]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX28_I]]
int8x8_t test_vtbx4_s8(int8x8_t a, int8x8x4_t b, int8x8_t c) {
return vtbx4_s8(a, b, c);
}
-// CHECK-LABEL: define <8 x i8> @test_vqtbx1_s8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #0 {
-// CHECK: [[VTBX1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #2
+// CHECK-LABEL: define <8 x i8> @test_vqtbx1_s8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #1 {
+// CHECK: [[VTBX1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX1_I]]
int8x8_t test_vqtbx1_s8(int8x8_t a, int8x16_t b, int8x8_t c) {
return vqtbx1_s8(a, b, c);
@@ -367,7 +367,7 @@ int8x8_t test_vqtbx1_s8(int8x8_t a, int8x16_t b, int8x8_t c) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBX2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %c) #2
+// CHECK: [[VTBX2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX2_I]]
int8x8_t test_vqtbx2_s8(int8x8_t a, int8x16x2_t b, int8x8_t c) {
return vqtbx2_s8(a, b, c);
@@ -391,7 +391,7 @@ int8x8_t test_vqtbx2_s8(int8x8_t a, int8x16x2_t b, int8x8_t c) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBX3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx3.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %c) #2
+// CHECK: [[VTBX3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx3.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX3_I]]
int8x8_t test_vqtbx3_s8(int8x8_t a, int8x16x3_t b, int8x8_t c) {
return vqtbx3_s8(a, b, c);
@@ -418,20 +418,20 @@ int8x8_t test_vqtbx3_s8(int8x8_t a, int8x16x3_t b, int8x8_t c) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBX4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx4.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %c) #2
+// CHECK: [[VTBX4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx4.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX4_I]]
int8x8_t test_vqtbx4_s8(int8x8_t a, int8x16x4_t b, int8x8_t c) {
return vqtbx4_s8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx1q_s8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #0 {
-// CHECK: [[VTBX1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #2
+// CHECK-LABEL: define <16 x i8> @test_vqtbx1q_s8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #1 {
+// CHECK: [[VTBX1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX1_I]]
int8x16_t test_vqtbx1q_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
return vqtbx1q_s8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx2q_s8(<16 x i8> %a, [2 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx2q_s8(<16 x i8> %a, [2 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[B]], i32 0, i32 0
@@ -446,13 +446,13 @@ int8x16_t test_vqtbx1q_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBX2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx2.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %c) #2
+// CHECK: [[VTBX2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx2.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX2_I]]
int8x16_t test_vqtbx2q_s8(int8x16_t a, int8x16x2_t b, int8x16_t c) {
return vqtbx2q_s8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx3q_s8(<16 x i8> %a, [3 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx3q_s8(<16 x i8> %a, [3 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[B]], i32 0, i32 0
@@ -470,13 +470,13 @@ int8x16_t test_vqtbx2q_s8(int8x16_t a, int8x16x2_t b, int8x16_t c) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBX3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx3.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %c) #2
+// CHECK: [[VTBX3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx3.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX3_I]]
int8x16_t test_vqtbx3q_s8(int8x16_t a, int8x16x3_t b, int8x16_t c) {
return vqtbx3q_s8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx4q_s8(<16 x i8> %a, [4 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx4q_s8(<16 x i8> %a, [4 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.int8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[B]], i32 0, i32 0
@@ -497,7 +497,7 @@ int8x16_t test_vqtbx3q_s8(int8x16_t a, int8x16x3_t b, int8x16_t c) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBX4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx4.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %c) #2
+// CHECK: [[VTBX4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx4.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX4_I]]
int8x16_t test_vqtbx4q_s8(int8x16_t a, int8x16x4_t b, int8x16_t c) {
return vqtbx4q_s8(a, b, c);
@@ -505,14 +505,14 @@ int8x16_t test_vqtbx4q_s8(int8x16_t a, int8x16x4_t b, int8x16_t c) {
// CHECK-LABEL: define <8 x i8> @test_vtbl1_u8(<8 x i8> %a, <8 x i8> %b) #0 {
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> %a, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL11_I]]
uint8x8_t test_vtbl1_u8(uint8x8_t a, uint8x8_t b) {
return vtbl1_u8(a, b);
}
-// CHECK-LABEL: define <8 x i8> @test_vqtbl1_u8(<16 x i8> %a, <8 x i8> %b) #0 {
-// CHECK: [[VTBL1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> %a, <8 x i8> %b) #2
+// CHECK-LABEL: define <8 x i8> @test_vqtbl1_u8(<16 x i8> %a, <8 x i8> %b) #1 {
+// CHECK: [[VTBL1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> %a, <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL1_I]]
uint8x8_t test_vqtbl1_u8(uint8x16_t a, uint8x8_t b) {
return vqtbl1_u8(a, b);
@@ -534,7 +534,7 @@ uint8x8_t test_vqtbl1_u8(uint8x16_t a, uint8x8_t b) {
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <8 x i8>], [2 x <8 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX2_I]], align 8
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL13_I]]
uint8x8_t test_vtbl2_u8(uint8x8x2_t a, uint8x8_t b) {
return vtbl2_u8(a, b);
@@ -555,7 +555,7 @@ uint8x8_t test_vtbl2_u8(uint8x8x2_t a, uint8x8_t b) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBL2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %b) #2
+// CHECK: [[VTBL2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL2_I]]
uint8x8_t test_vqtbl2_u8(uint8x16x2_t a, uint8x8_t b) {
return vqtbl2_u8(a, b);
@@ -581,7 +581,7 @@ uint8x8_t test_vqtbl2_u8(uint8x16x2_t a, uint8x8_t b) {
// CHECK: [[TMP3:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX4_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL25_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL26_I]]
uint8x8_t test_vtbl3_u8(uint8x8x3_t a, uint8x8_t b) {
return vtbl3_u8(a, b);
@@ -605,7 +605,7 @@ uint8x8_t test_vtbl3_u8(uint8x8x3_t a, uint8x8_t b) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBL3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl3.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %b) #2
+// CHECK: [[VTBL3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl3.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL3_I]]
uint8x8_t test_vqtbl3_u8(uint8x16x3_t a, uint8x8_t b) {
return vqtbl3_u8(a, b);
@@ -634,7 +634,7 @@ uint8x8_t test_vqtbl3_u8(uint8x16x3_t a, uint8x8_t b) {
// CHECK: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX6_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL27_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL27_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL27_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL28_I]]
uint8x8_t test_vtbl4_u8(uint8x8x4_t a, uint8x8_t b) {
return vtbl4_u8(a, b);
@@ -661,20 +661,20 @@ uint8x8_t test_vtbl4_u8(uint8x8x4_t a, uint8x8_t b) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBL4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl4.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %b) #2
+// CHECK: [[VTBL4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl4.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL4_I]]
uint8x8_t test_vqtbl4_u8(uint8x16x4_t a, uint8x8_t b) {
return vqtbl4_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl1q_u8(<16 x i8> %a, <16 x i8> %b) #0 {
-// CHECK: [[VTBL1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl1.v16i8(<16 x i8> %a, <16 x i8> %b) #2
+// CHECK-LABEL: define <16 x i8> @test_vqtbl1q_u8(<16 x i8> %a, <16 x i8> %b) #1 {
+// CHECK: [[VTBL1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl1.v16i8(<16 x i8> %a, <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL1_I]]
uint8x16_t test_vqtbl1q_u8(uint8x16_t a, uint8x16_t b) {
return vqtbl1q_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl2q_u8([2 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl2q_u8([2 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[A]], i32 0, i32 0
@@ -689,13 +689,13 @@ uint8x16_t test_vqtbl1q_u8(uint8x16_t a, uint8x16_t b) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBL2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %b) #2
+// CHECK: [[VTBL2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL2_I]]
uint8x16_t test_vqtbl2q_u8(uint8x16x2_t a, uint8x16_t b) {
return vqtbl2q_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl3q_u8([3 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl3q_u8([3 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[A]], i32 0, i32 0
@@ -713,13 +713,13 @@ uint8x16_t test_vqtbl2q_u8(uint8x16x2_t a, uint8x16_t b) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBL3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl3.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %b) #2
+// CHECK: [[VTBL3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl3.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL3_I]]
uint8x16_t test_vqtbl3q_u8(uint8x16x3_t a, uint8x16_t b) {
return vqtbl3q_u8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl4q_u8([4 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl4q_u8([4 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[A]], i32 0, i32 0
@@ -740,7 +740,7 @@ uint8x16_t test_vqtbl3q_u8(uint8x16x3_t a, uint8x16_t b) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBL4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl4.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %b) #2
+// CHECK: [[VTBL4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl4.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL4_I]]
uint8x16_t test_vqtbl4q_u8(uint8x16x4_t a, uint8x16_t b) {
return vqtbl4q_u8(a, b);
@@ -748,7 +748,7 @@ uint8x16_t test_vqtbl4q_u8(uint8x16x4_t a, uint8x16_t b) {
// CHECK-LABEL: define <8 x i8> @test_vtbx1_u8(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) #0 {
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> %b, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %c) #2
+// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %c) #3
// CHECK: [[TMP0:%.*]] = icmp uge <8 x i8> %c, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
// CHECK: [[TMP1:%.*]] = sext <8 x i1> [[TMP0]] to <8 x i8>
// CHECK: [[TMP2:%.*]] = and <8 x i8> [[TMP1]], %a
@@ -776,7 +776,7 @@ uint8x8_t test_vtbx1_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <8 x i8>], [2 x <8 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX2_I]], align 8
// CHECK: [[VTBX1_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBX13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> [[VTBX1_I]], <8 x i8> %c) #2
+// CHECK: [[VTBX13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> [[VTBX1_I]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX13_I]]
uint8x8_t test_vtbx2_u8(uint8x8_t a, uint8x8x2_t b, uint8x8_t c) {
return vtbx2_u8(a, b, c);
@@ -802,7 +802,7 @@ uint8x8_t test_vtbx2_u8(uint8x8_t a, uint8x8x2_t b, uint8x8_t c) {
// CHECK: [[TMP3:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX4_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL25_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %c) #2
+// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %c) #3
// CHECK: [[TMP4:%.*]] = icmp uge <8 x i8> %c, <i8 24, i8 24, i8 24, i8 24, i8 24, i8 24, i8 24, i8 24>
// CHECK: [[TMP5:%.*]] = sext <8 x i1> [[TMP4]] to <8 x i8>
// CHECK: [[TMP6:%.*]] = and <8 x i8> [[TMP5]], %a
@@ -837,14 +837,14 @@ uint8x8_t test_vtbx3_u8(uint8x8_t a, uint8x8x3_t b, uint8x8_t c) {
// CHECK: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX6_I]], align 8
// CHECK: [[VTBX2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBX27_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBX28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[VTBX2_I]], <16 x i8> [[VTBX27_I]], <8 x i8> %c) #2
+// CHECK: [[VTBX28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[VTBX2_I]], <16 x i8> [[VTBX27_I]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX28_I]]
uint8x8_t test_vtbx4_u8(uint8x8_t a, uint8x8x4_t b, uint8x8_t c) {
return vtbx4_u8(a, b, c);
}
-// CHECK-LABEL: define <8 x i8> @test_vqtbx1_u8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #0 {
-// CHECK: [[VTBX1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #2
+// CHECK-LABEL: define <8 x i8> @test_vqtbx1_u8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #1 {
+// CHECK: [[VTBX1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX1_I]]
uint8x8_t test_vqtbx1_u8(uint8x8_t a, uint8x16_t b, uint8x8_t c) {
return vqtbx1_u8(a, b, c);
@@ -865,7 +865,7 @@ uint8x8_t test_vqtbx1_u8(uint8x8_t a, uint8x16_t b, uint8x8_t c) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBX2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %c) #2
+// CHECK: [[VTBX2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX2_I]]
uint8x8_t test_vqtbx2_u8(uint8x8_t a, uint8x16x2_t b, uint8x8_t c) {
return vqtbx2_u8(a, b, c);
@@ -889,7 +889,7 @@ uint8x8_t test_vqtbx2_u8(uint8x8_t a, uint8x16x2_t b, uint8x8_t c) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBX3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx3.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %c) #2
+// CHECK: [[VTBX3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx3.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX3_I]]
uint8x8_t test_vqtbx3_u8(uint8x8_t a, uint8x16x3_t b, uint8x8_t c) {
return vqtbx3_u8(a, b, c);
@@ -916,20 +916,20 @@ uint8x8_t test_vqtbx3_u8(uint8x8_t a, uint8x16x3_t b, uint8x8_t c) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBX4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx4.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %c) #2
+// CHECK: [[VTBX4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx4.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX4_I]]
uint8x8_t test_vqtbx4_u8(uint8x8_t a, uint8x16x4_t b, uint8x8_t c) {
return vqtbx4_u8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx1q_u8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #0 {
-// CHECK: [[VTBX1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #2
+// CHECK-LABEL: define <16 x i8> @test_vqtbx1q_u8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #1 {
+// CHECK: [[VTBX1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX1_I]]
uint8x16_t test_vqtbx1q_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
return vqtbx1q_u8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx2q_u8(<16 x i8> %a, [2 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx2q_u8(<16 x i8> %a, [2 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[B]], i32 0, i32 0
@@ -944,13 +944,13 @@ uint8x16_t test_vqtbx1q_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.uint8x16x2_t, %struct.uint8x16x2_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBX2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx2.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %c) #2
+// CHECK: [[VTBX2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx2.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX2_I]]
uint8x16_t test_vqtbx2q_u8(uint8x16_t a, uint8x16x2_t b, uint8x16_t c) {
return vqtbx2q_u8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx3q_u8(<16 x i8> %a, [3 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx3q_u8(<16 x i8> %a, [3 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[B]], i32 0, i32 0
@@ -968,13 +968,13 @@ uint8x16_t test_vqtbx2q_u8(uint8x16_t a, uint8x16x2_t b, uint8x16_t c) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.uint8x16x3_t, %struct.uint8x16x3_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBX3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx3.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %c) #2
+// CHECK: [[VTBX3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx3.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX3_I]]
uint8x16_t test_vqtbx3q_u8(uint8x16_t a, uint8x16x3_t b, uint8x16_t c) {
return vqtbx3q_u8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx4q_u8(<16 x i8> %a, [4 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx4q_u8(<16 x i8> %a, [4 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.uint8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[B]], i32 0, i32 0
@@ -995,7 +995,7 @@ uint8x16_t test_vqtbx3q_u8(uint8x16_t a, uint8x16x3_t b, uint8x16_t c) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.uint8x16x4_t, %struct.uint8x16x4_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBX4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx4.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %c) #2
+// CHECK: [[VTBX4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx4.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX4_I]]
uint8x16_t test_vqtbx4q_u8(uint8x16_t a, uint8x16x4_t b, uint8x16_t c) {
return vqtbx4q_u8(a, b, c);
@@ -1003,14 +1003,14 @@ uint8x16_t test_vqtbx4q_u8(uint8x16_t a, uint8x16x4_t b, uint8x16_t c) {
// CHECK-LABEL: define <8 x i8> @test_vtbl1_p8(<8 x i8> %a, <8 x i8> %b) #0 {
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> %a, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL11_I]]
poly8x8_t test_vtbl1_p8(poly8x8_t a, uint8x8_t b) {
return vtbl1_p8(a, b);
}
-// CHECK-LABEL: define <8 x i8> @test_vqtbl1_p8(<16 x i8> %a, <8 x i8> %b) #0 {
-// CHECK: [[VTBL1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> %a, <8 x i8> %b) #2
+// CHECK-LABEL: define <8 x i8> @test_vqtbl1_p8(<16 x i8> %a, <8 x i8> %b) #1 {
+// CHECK: [[VTBL1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> %a, <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL1_I]]
poly8x8_t test_vqtbl1_p8(poly8x16_t a, uint8x8_t b) {
return vqtbl1_p8(a, b);
@@ -1032,7 +1032,7 @@ poly8x8_t test_vqtbl1_p8(poly8x16_t a, uint8x8_t b) {
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <8 x i8>], [2 x <8 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX2_I]], align 8
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL13_I]]
poly8x8_t test_vtbl2_p8(poly8x8x2_t a, uint8x8_t b) {
return vtbl2_p8(a, b);
@@ -1053,7 +1053,7 @@ poly8x8_t test_vtbl2_p8(poly8x8x2_t a, uint8x8_t b) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBL2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %b) #2
+// CHECK: [[VTBL2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL2_I]]
poly8x8_t test_vqtbl2_p8(poly8x16x2_t a, uint8x8_t b) {
return vqtbl2_p8(a, b);
@@ -1079,7 +1079,7 @@ poly8x8_t test_vqtbl2_p8(poly8x16x2_t a, uint8x8_t b) {
// CHECK: [[TMP3:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX4_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL25_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL26_I]]
poly8x8_t test_vtbl3_p8(poly8x8x3_t a, uint8x8_t b) {
return vtbl3_p8(a, b);
@@ -1103,7 +1103,7 @@ poly8x8_t test_vtbl3_p8(poly8x8x3_t a, uint8x8_t b) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBL3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl3.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %b) #2
+// CHECK: [[VTBL3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl3.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL3_I]]
poly8x8_t test_vqtbl3_p8(poly8x16x3_t a, uint8x8_t b) {
return vqtbl3_p8(a, b);
@@ -1132,7 +1132,7 @@ poly8x8_t test_vqtbl3_p8(poly8x16x3_t a, uint8x8_t b) {
// CHECK: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX6_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL27_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL27_I]], <8 x i8> %b) #2
+// CHECK: [[VTBL28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL27_I]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL28_I]]
poly8x8_t test_vtbl4_p8(poly8x8x4_t a, uint8x8_t b) {
return vtbl4_p8(a, b);
@@ -1159,20 +1159,20 @@ poly8x8_t test_vtbl4_p8(poly8x8x4_t a, uint8x8_t b) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBL4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl4.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %b) #2
+// CHECK: [[VTBL4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl4.v8i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %b) #3
// CHECK: ret <8 x i8> [[VTBL4_I]]
poly8x8_t test_vqtbl4_p8(poly8x16x4_t a, uint8x8_t b) {
return vqtbl4_p8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl1q_p8(<16 x i8> %a, <16 x i8> %b) #0 {
-// CHECK: [[VTBL1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl1.v16i8(<16 x i8> %a, <16 x i8> %b) #2
+// CHECK-LABEL: define <16 x i8> @test_vqtbl1q_p8(<16 x i8> %a, <16 x i8> %b) #1 {
+// CHECK: [[VTBL1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl1.v16i8(<16 x i8> %a, <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL1_I]]
poly8x16_t test_vqtbl1q_p8(poly8x16_t a, uint8x16_t b) {
return vqtbl1q_p8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl2q_p8([2 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl2q_p8([2 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[A]], i32 0, i32 0
@@ -1187,13 +1187,13 @@ poly8x16_t test_vqtbl1q_p8(poly8x16_t a, uint8x16_t b) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBL2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %b) #2
+// CHECK: [[VTBL2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL2_I]]
poly8x16_t test_vqtbl2q_p8(poly8x16x2_t a, uint8x16_t b) {
return vqtbl2q_p8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl3q_p8([3 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl3q_p8([3 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[A]], i32 0, i32 0
@@ -1211,13 +1211,13 @@ poly8x16_t test_vqtbl2q_p8(poly8x16x2_t a, uint8x16_t b) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBL3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl3.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %b) #2
+// CHECK: [[VTBL3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl3.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL3_I]]
poly8x16_t test_vqtbl3q_p8(poly8x16x3_t a, uint8x16_t b) {
return vqtbl3q_p8(a, b);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbl4q_p8([4 x <16 x i8>] %a.coerce, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbl4q_p8([4 x <16 x i8>] %a.coerce, <16 x i8> %b) #1 {
// CHECK: [[__P0_I:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[A:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[A]], i32 0, i32 0
@@ -1238,7 +1238,7 @@ poly8x16_t test_vqtbl3q_p8(poly8x16x3_t a, uint8x16_t b) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[__P0_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBL4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl4.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %b) #2
+// CHECK: [[VTBL4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbl4.v16i8(<16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %b) #3
// CHECK: ret <16 x i8> [[VTBL4_I]]
poly8x16_t test_vqtbl4q_p8(poly8x16x4_t a, uint8x16_t b) {
return vqtbl4q_p8(a, b);
@@ -1246,7 +1246,7 @@ poly8x16_t test_vqtbl4q_p8(poly8x16x4_t a, uint8x16_t b) {
// CHECK-LABEL: define <8 x i8> @test_vtbx1_p8(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) #0 {
// CHECK: [[VTBL1_I:%.*]] = shufflevector <8 x i8> %b, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %c) #2
+// CHECK: [[VTBL11_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl1.v8i8(<16 x i8> [[VTBL1_I]], <8 x i8> %c) #3
// CHECK: [[TMP0:%.*]] = icmp uge <8 x i8> %c, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
// CHECK: [[TMP1:%.*]] = sext <8 x i1> [[TMP0]] to <8 x i8>
// CHECK: [[TMP2:%.*]] = and <8 x i8> [[TMP1]], %a
@@ -1274,7 +1274,7 @@ poly8x8_t test_vtbx1_p8(poly8x8_t a, poly8x8_t b, uint8x8_t c) {
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <8 x i8>], [2 x <8 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX2_I]], align 8
// CHECK: [[VTBX1_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBX13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> [[VTBX1_I]], <8 x i8> %c) #2
+// CHECK: [[VTBX13_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> [[VTBX1_I]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX13_I]]
poly8x8_t test_vtbx2_p8(poly8x8_t a, poly8x8x2_t b, uint8x8_t c) {
return vtbx2_p8(a, b, c);
@@ -1300,7 +1300,7 @@ poly8x8_t test_vtbx2_p8(poly8x8_t a, poly8x8x2_t b, uint8x8_t c) {
// CHECK: [[TMP3:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX4_I]], align 8
// CHECK: [[VTBL2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBL25_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %c) #2
+// CHECK: [[VTBL26_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbl2.v8i8(<16 x i8> [[VTBL2_I]], <16 x i8> [[VTBL25_I]], <8 x i8> %c) #3
// CHECK: [[TMP4:%.*]] = icmp uge <8 x i8> %c, <i8 24, i8 24, i8 24, i8 24, i8 24, i8 24, i8 24, i8 24>
// CHECK: [[TMP5:%.*]] = sext <8 x i1> [[TMP4]] to <8 x i8>
// CHECK: [[TMP6:%.*]] = and <8 x i8> [[TMP5]], %a
@@ -1335,14 +1335,14 @@ poly8x8_t test_vtbx3_p8(poly8x8_t a, poly8x8x3_t b, uint8x8_t c) {
// CHECK: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[ARRAYIDX6_I]], align 8
// CHECK: [[VTBX2_I:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
// CHECK: [[VTBX27_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK: [[VTBX28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[VTBX2_I]], <16 x i8> [[VTBX27_I]], <8 x i8> %c) #2
+// CHECK: [[VTBX28_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[VTBX2_I]], <16 x i8> [[VTBX27_I]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX28_I]]
poly8x8_t test_vtbx4_p8(poly8x8_t a, poly8x8x4_t b, uint8x8_t c) {
return vtbx4_p8(a, b, c);
}
-// CHECK-LABEL: define <8 x i8> @test_vqtbx1_p8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #0 {
-// CHECK: [[VTBX1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #2
+// CHECK-LABEL: define <8 x i8> @test_vqtbx1_p8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #1 {
+// CHECK: [[VTBX1_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8> %a, <16 x i8> %b, <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX1_I]]
poly8x8_t test_vqtbx1_p8(poly8x8_t a, uint8x16_t b, uint8x8_t c) {
return vqtbx1_p8(a, b, c);
@@ -1363,7 +1363,7 @@ poly8x8_t test_vqtbx1_p8(poly8x8_t a, uint8x16_t b, uint8x8_t c) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBX2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %c) #2
+// CHECK: [[VTBX2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX2_I]]
poly8x8_t test_vqtbx2_p8(poly8x8_t a, poly8x16x2_t b, uint8x8_t c) {
return vqtbx2_p8(a, b, c);
@@ -1387,7 +1387,7 @@ poly8x8_t test_vqtbx2_p8(poly8x8_t a, poly8x16x2_t b, uint8x8_t c) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBX3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx3.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %c) #2
+// CHECK: [[VTBX3_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx3.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX3_I]]
poly8x8_t test_vqtbx3_p8(poly8x8_t a, poly8x16x3_t b, uint8x8_t c) {
return vqtbx3_p8(a, b, c);
@@ -1414,20 +1414,20 @@ poly8x8_t test_vqtbx3_p8(poly8x8_t a, poly8x16x3_t b, uint8x8_t c) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBX4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx4.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %c) #2
+// CHECK: [[VTBX4_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.tbx4.v8i8(<8 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <8 x i8> %c) #3
// CHECK: ret <8 x i8> [[VTBX4_I]]
poly8x8_t test_vqtbx4_p8(poly8x8_t a, poly8x16x4_t b, uint8x8_t c) {
return vqtbx4_p8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx1q_p8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #0 {
-// CHECK: [[VTBX1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #2
+// CHECK-LABEL: define <16 x i8> @test_vqtbx1q_p8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #1 {
+// CHECK: [[VTBX1_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX1_I]]
poly8x16_t test_vqtbx1q_p8(poly8x16_t a, uint8x16_t b, uint8x16_t c) {
return vqtbx1q_p8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx2q_p8(<16 x i8> %a, [2 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx2q_p8(<16 x i8> %a, [2 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[B]], i32 0, i32 0
@@ -1442,13 +1442,13 @@ poly8x16_t test_vqtbx1q_p8(poly8x16_t a, uint8x16_t b, uint8x16_t c) {
// CHECK: [[VAL1_I:%.*]] = getelementptr inbounds %struct.poly8x16x2_t, %struct.poly8x16x2_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds [2 x <16 x i8>], [2 x <16 x i8>]* [[VAL1_I]], i64 0, i64 1
// CHECK: [[TMP2:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX2_I]], align 16
-// CHECK: [[VTBX2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx2.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %c) #2
+// CHECK: [[VTBX2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx2.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX2_I]]
poly8x16_t test_vqtbx2q_p8(poly8x16_t a, poly8x16x2_t b, uint8x16_t c) {
return vqtbx2q_p8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx3q_p8(<16 x i8> %a, [3 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx3q_p8(<16 x i8> %a, [3 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[B]], i32 0, i32 0
@@ -1466,13 +1466,13 @@ poly8x16_t test_vqtbx2q_p8(poly8x16_t a, poly8x16x2_t b, uint8x16_t c) {
// CHECK: [[VAL3_I:%.*]] = getelementptr inbounds %struct.poly8x16x3_t, %struct.poly8x16x3_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX4_I:%.*]] = getelementptr inbounds [3 x <16 x i8>], [3 x <16 x i8>]* [[VAL3_I]], i64 0, i64 2
// CHECK: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX4_I]], align 16
-// CHECK: [[VTBX3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx3.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %c) #2
+// CHECK: [[VTBX3_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx3.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX3_I]]
poly8x16_t test_vqtbx3q_p8(poly8x16_t a, poly8x16x3_t b, uint8x16_t c) {
return vqtbx3q_p8(a, b, c);
}
-// CHECK-LABEL: define <16 x i8> @test_vqtbx4q_p8(<16 x i8> %a, [4 x <16 x i8>] %b.coerce, <16 x i8> %c) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vqtbx4q_p8(<16 x i8> %a, [4 x <16 x i8>] %b.coerce, <16 x i8> %c) #1 {
// CHECK: [[__P1_I:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[B:%.*]] = alloca %struct.poly8x16x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[B]], i32 0, i32 0
@@ -1493,8 +1493,11 @@ poly8x16_t test_vqtbx3q_p8(poly8x16_t a, poly8x16x3_t b, uint8x16_t c) {
// CHECK: [[VAL5_I:%.*]] = getelementptr inbounds %struct.poly8x16x4_t, %struct.poly8x16x4_t* [[__P1_I]], i32 0, i32 0
// CHECK: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x <16 x i8>], [4 x <16 x i8>]* [[VAL5_I]], i64 0, i64 3
// CHECK: [[TMP4:%.*]] = load <16 x i8>, <16 x i8>* [[ARRAYIDX6_I]], align 16
-// CHECK: [[VTBX4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx4.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %c) #2
+// CHECK: [[VTBX4_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.tbx4.v16i8(<16 x i8> %a, <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], <16 x i8> [[TMP3]], <16 x i8> [[TMP4]], <16 x i8> %c) #3
// CHECK: ret <16 x i8> [[VTBX4_I]]
poly8x16_t test_vqtbx4q_p8(poly8x16_t a, poly8x16x4_t b, uint8x16_t c) {
return vqtbx4q_p8(a, b, c);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-neon-vget.c b/test/CodeGen/aarch64-neon-vget.c
index ac7bc2d68a..cd25ec3ee2 100644
--- a/test/CodeGen/aarch64-neon-vget.c
+++ b/test/CodeGen/aarch64-neon-vget.c
@@ -97,14 +97,14 @@ float32_t test_vget_lane_f16(float16x4_t a) {
return vget_lane_f16(a, 1);
}
-// CHECK-LABEL: define i8 @test_vgetq_lane_u8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i8 @test_vgetq_lane_u8(<16 x i8> %a) #1 {
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <16 x i8> %a, i32 15
// CHECK: ret i8 [[VGETQ_LANE]]
uint8_t test_vgetq_lane_u8(uint8x16_t a) {
return vgetq_lane_u8(a, 15);
}
-// CHECK-LABEL: define i16 @test_vgetq_lane_u16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i16 @test_vgetq_lane_u16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -113,7 +113,7 @@ uint16_t test_vgetq_lane_u16(uint16x8_t a) {
return vgetq_lane_u16(a, 7);
}
-// CHECK-LABEL: define i32 @test_vgetq_lane_u32(<4 x i32> %a) #0 {
+// CHECK-LABEL: define i32 @test_vgetq_lane_u32(<4 x i32> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -122,14 +122,14 @@ uint32_t test_vgetq_lane_u32(uint32x4_t a) {
return vgetq_lane_u32(a, 3);
}
-// CHECK-LABEL: define i8 @test_vgetq_lane_s8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i8 @test_vgetq_lane_s8(<16 x i8> %a) #1 {
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <16 x i8> %a, i32 15
// CHECK: ret i8 [[VGETQ_LANE]]
int8_t test_vgetq_lane_s8(int8x16_t a) {
return vgetq_lane_s8(a, 15);
}
-// CHECK-LABEL: define i16 @test_vgetq_lane_s16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i16 @test_vgetq_lane_s16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -138,7 +138,7 @@ int16_t test_vgetq_lane_s16(int16x8_t a) {
return vgetq_lane_s16(a, 7);
}
-// CHECK-LABEL: define i32 @test_vgetq_lane_s32(<4 x i32> %a) #0 {
+// CHECK-LABEL: define i32 @test_vgetq_lane_s32(<4 x i32> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x i32> [[TMP1]], i32 3
@@ -147,14 +147,14 @@ int32_t test_vgetq_lane_s32(int32x4_t a) {
return vgetq_lane_s32(a, 3);
}
-// CHECK-LABEL: define i8 @test_vgetq_lane_p8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i8 @test_vgetq_lane_p8(<16 x i8> %a) #1 {
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <16 x i8> %a, i32 15
// CHECK: ret i8 [[VGETQ_LANE]]
poly8_t test_vgetq_lane_p8(poly8x16_t a) {
return vgetq_lane_p8(a, 15);
}
-// CHECK-LABEL: define i16 @test_vgetq_lane_p16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i16 @test_vgetq_lane_p16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7
@@ -163,7 +163,7 @@ poly16_t test_vgetq_lane_p16(poly16x8_t a) {
return vgetq_lane_p16(a, 7);
}
-// CHECK-LABEL: define float @test_vgetq_lane_f32(<4 x float> %a) #0 {
+// CHECK-LABEL: define float @test_vgetq_lane_f32(<4 x float> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <4 x float> [[TMP1]], i32 3
@@ -172,7 +172,7 @@ float32_t test_vgetq_lane_f32(float32x4_t a) {
return vgetq_lane_f32(a, 3);
}
-// CHECK-LABEL: define float @test_vgetq_lane_f16(<8 x half> %a) #0 {
+// CHECK-LABEL: define float @test_vgetq_lane_f16(<8 x half> %a) #1 {
// CHECK: [[__REINT_244:%.*]] = alloca <8 x half>, align 16
// CHECK: [[__REINT1_244:%.*]] = alloca i16, align 2
// CHECK: store <8 x half> %a, <8 x half>* [[__REINT_244]], align 16
@@ -208,7 +208,7 @@ uint64_t test_vget_lane_u64(uint64x1_t a) {
return vget_lane_u64(a, 0);
}
-// CHECK-LABEL: define i64 @test_vgetq_lane_s64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i64 @test_vgetq_lane_s64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
@@ -217,7 +217,7 @@ int64_t test_vgetq_lane_s64(int64x2_t a) {
return vgetq_lane_s64(a, 1);
}
-// CHECK-LABEL: define i64 @test_vgetq_lane_u64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i64 @test_vgetq_lane_u64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
@@ -324,14 +324,14 @@ float16x4_t test_vset_lane_f16(float16_t *a, float16x4_t b) {
return vset_lane_f16(*a, b, 3);
}
-// CHECK-LABEL: define <16 x i8> @test_vsetq_lane_u8(i8 %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vsetq_lane_u8(i8 %a, <16 x i8> %b) #1 {
// CHECK: [[VSET_LANE:%.*]] = insertelement <16 x i8> %b, i8 %a, i32 15
// CHECK: ret <16 x i8> [[VSET_LANE]]
uint8x16_t test_vsetq_lane_u8(uint8_t a, uint8x16_t b) {
return vsetq_lane_u8(a, b, 15);
}
-// CHECK-LABEL: define <8 x i16> @test_vsetq_lane_u16(i16 %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vsetq_lane_u16(i16 %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VSET_LANE:%.*]] = insertelement <8 x i16> [[TMP1]], i16 %a, i32 7
@@ -340,7 +340,7 @@ uint16x8_t test_vsetq_lane_u16(uint16_t a, uint16x8_t b) {
return vsetq_lane_u16(a, b, 7);
}
-// CHECK-LABEL: define <4 x i32> @test_vsetq_lane_u32(i32 %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vsetq_lane_u32(i32 %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VSET_LANE:%.*]] = insertelement <4 x i32> [[TMP1]], i32 %a, i32 3
@@ -349,14 +349,14 @@ uint32x4_t test_vsetq_lane_u32(uint32_t a, uint32x4_t b) {
return vsetq_lane_u32(a, b, 3);
}
-// CHECK-LABEL: define <16 x i8> @test_vsetq_lane_s8(i8 %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vsetq_lane_s8(i8 %a, <16 x i8> %b) #1 {
// CHECK: [[VSET_LANE:%.*]] = insertelement <16 x i8> %b, i8 %a, i32 15
// CHECK: ret <16 x i8> [[VSET_LANE]]
int8x16_t test_vsetq_lane_s8(int8_t a, int8x16_t b) {
return vsetq_lane_s8(a, b, 15);
}
-// CHECK-LABEL: define <8 x i16> @test_vsetq_lane_s16(i16 %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vsetq_lane_s16(i16 %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VSET_LANE:%.*]] = insertelement <8 x i16> [[TMP1]], i16 %a, i32 7
@@ -365,7 +365,7 @@ int16x8_t test_vsetq_lane_s16(int16_t a, int16x8_t b) {
return vsetq_lane_s16(a, b, 7);
}
-// CHECK-LABEL: define <4 x i32> @test_vsetq_lane_s32(i32 %a, <4 x i32> %b) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vsetq_lane_s32(i32 %a, <4 x i32> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
// CHECK: [[VSET_LANE:%.*]] = insertelement <4 x i32> [[TMP1]], i32 %a, i32 3
@@ -374,14 +374,14 @@ int32x4_t test_vsetq_lane_s32(int32_t a, int32x4_t b) {
return vsetq_lane_s32(a, b, 3);
}
-// CHECK-LABEL: define <16 x i8> @test_vsetq_lane_p8(i8 %a, <16 x i8> %b) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vsetq_lane_p8(i8 %a, <16 x i8> %b) #1 {
// CHECK: [[VSET_LANE:%.*]] = insertelement <16 x i8> %b, i8 %a, i32 15
// CHECK: ret <16 x i8> [[VSET_LANE]]
poly8x16_t test_vsetq_lane_p8(poly8_t a, poly8x16_t b) {
return vsetq_lane_p8(a, b, 15);
}
-// CHECK-LABEL: define <8 x i16> @test_vsetq_lane_p16(i16 %a, <8 x i16> %b) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vsetq_lane_p16(i16 %a, <8 x i16> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
// CHECK: [[VSET_LANE:%.*]] = insertelement <8 x i16> [[TMP1]], i16 %a, i32 7
@@ -390,7 +390,7 @@ poly16x8_t test_vsetq_lane_p16(poly16_t a, poly16x8_t b) {
return vsetq_lane_p16(a, b, 7);
}
-// CHECK-LABEL: define <4 x float> @test_vsetq_lane_f32(float %a, <4 x float> %b) #0 {
+// CHECK-LABEL: define <4 x float> @test_vsetq_lane_f32(float %a, <4 x float> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float>
// CHECK: [[VSET_LANE:%.*]] = insertelement <4 x float> [[TMP1]], float %a, i32 3
@@ -399,7 +399,7 @@ float32x4_t test_vsetq_lane_f32(float32_t a, float32x4_t b) {
return vsetq_lane_f32(a, b, 3);
}
-// CHECK-LABEL: define <8 x half> @test_vsetq_lane_f16(half* %a, <8 x half> %b) #0 {
+// CHECK-LABEL: define <8 x half> @test_vsetq_lane_f16(half* %a, <8 x half> %b) #1 {
// CHECK: [[__REINT_248:%.*]] = alloca half, align 2
// CHECK: [[__REINT1_248:%.*]] = alloca <8 x half>, align 16
// CHECK: [[__REINT2_248:%.*]] = alloca <8 x i16>, align 16
@@ -439,7 +439,7 @@ uint64x1_t test_vset_lane_u64(uint64_t a, uint64x1_t b) {
return vset_lane_u64(a, b, 0);
}
-// CHECK-LABEL: define <2 x i64> @test_vsetq_lane_s64(i64 %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vsetq_lane_s64(i64 %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VSET_LANE:%.*]] = insertelement <2 x i64> [[TMP1]], i64 %a, i32 1
@@ -448,7 +448,7 @@ int64x2_t test_vsetq_lane_s64(int64_t a, int64x2_t b) {
return vsetq_lane_s64(a, b, 1);
}
-// CHECK-LABEL: define <2 x i64> @test_vsetq_lane_u64(i64 %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vsetq_lane_u64(i64 %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VSET_LANE:%.*]] = insertelement <2 x i64> [[TMP1]], i64 %a, i32 1
@@ -456,3 +456,6 @@ int64x2_t test_vsetq_lane_s64(int64_t a, int64x2_t b) {
uint64x2_t test_vsetq_lane_u64(uint64_t a, uint64x2_t b) {
return vsetq_lane_u64(a, b, 1);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/aarch64-poly128.c b/test/CodeGen/aarch64-poly128.c
index d33d936717..d139cfecb3 100644
--- a/test/CodeGen/aarch64-poly128.c
+++ b/test/CodeGen/aarch64-poly128.c
@@ -47,201 +47,201 @@ void test_ld_st_p128(poly128_t * ptr) {
}
// CHECK-LABEL: define i128 @test_vmull_p64(i64 %a, i64 %b) #0 {
-// CHECK: [[VMULL_P64_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 %a, i64 %b) #2
+// CHECK: [[VMULL_P64_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 %a, i64 %b) #3
// CHECK: [[VMULL_P641_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I]] to i128
// CHECK: ret i128 [[VMULL_P641_I]]
poly128_t test_vmull_p64(poly64_t a, poly64_t b) {
return vmull_p64(a, b);
}
-// CHECK-LABEL: define i128 @test_vmull_high_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define i128 @test_vmull_high_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %a, <1 x i32> <i32 1>
// CHECK: [[TMP0:%.*]] = bitcast <1 x i64> [[SHUFFLE_I_I]] to i64
// CHECK: [[SHUFFLE_I7_I:%.*]] = shufflevector <2 x i64> %b, <2 x i64> %b, <1 x i32> <i32 1>
// CHECK: [[TMP1:%.*]] = bitcast <1 x i64> [[SHUFFLE_I7_I]] to i64
-// CHECK: [[VMULL_P64_I_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[TMP0]], i64 [[TMP1]]) #2
+// CHECK: [[VMULL_P64_I_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[TMP0]], i64 [[TMP1]]) #3
// CHECK: [[VMULL_P641_I_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I_I]] to i128
// CHECK: ret i128 [[VMULL_P641_I_I]]
poly128_t test_vmull_high_p64(poly64x2_t a, poly64x2_t b) {
return vmull_high_p64(a, b);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s8(<16 x i8> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <16 x i8> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_s8(int8x16_t a) {
return vreinterpretq_p128_s8(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_s16(int16x8_t a) {
return vreinterpretq_p128_s16(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s32(<4 x i32> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s32(<4 x i32> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_s32(int32x4_t a) {
return vreinterpretq_p128_s32(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_s64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_s64(int64x2_t a) {
return vreinterpretq_p128_s64(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u8(<16 x i8> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <16 x i8> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_u8(uint8x16_t a) {
return vreinterpretq_p128_u8(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_u16(uint16x8_t a) {
return vreinterpretq_p128_u16(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u32(<4 x i32> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u32(<4 x i32> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x i32> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_u32(uint32x4_t a) {
return vreinterpretq_p128_u32(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_u64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_u64(uint64x2_t a) {
return vreinterpretq_p128_u64(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_f32(<4 x float> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_f32(<4 x float> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_f32(float32x4_t a) {
return vreinterpretq_p128_f32(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_f64(<2 x double> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_f64(<2 x double> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_f64(float64x2_t a) {
return vreinterpretq_p128_f64(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_p8(<16 x i8> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_p8(<16 x i8> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <16 x i8> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_p8(poly8x16_t a) {
return vreinterpretq_p128_p8(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_p16(<8 x i16> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_p16(<8 x i16> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <8 x i16> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_p16(poly16x8_t a) {
return vreinterpretq_p128_p16(a);
}
-// CHECK-LABEL: define i128 @test_vreinterpretq_p128_p64(<2 x i64> %a) #0 {
+// CHECK-LABEL: define i128 @test_vreinterpretq_p128_p64(<2 x i64> %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to i128
// CHECK: ret i128 [[TMP0]]
poly128_t test_vreinterpretq_p128_p64(poly64x2_t a) {
return vreinterpretq_p128_p64(a);
}
-// CHECK-LABEL: define <16 x i8> @test_vreinterpretq_s8_p128(i128 %a) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vreinterpretq_s8_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <16 x i8>
// CHECK: ret <16 x i8> [[TMP0]]
int8x16_t test_vreinterpretq_s8_p128(poly128_t a) {
return vreinterpretq_s8_p128(a);
}
-// CHECK-LABEL: define <8 x i16> @test_vreinterpretq_s16_p128(i128 %a) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vreinterpretq_s16_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <8 x i16>
// CHECK: ret <8 x i16> [[TMP0]]
int16x8_t test_vreinterpretq_s16_p128(poly128_t a) {
return vreinterpretq_s16_p128(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vreinterpretq_s32_p128(i128 %a) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vreinterpretq_s32_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <4 x i32>
// CHECK: ret <4 x i32> [[TMP0]]
int32x4_t test_vreinterpretq_s32_p128(poly128_t a) {
return vreinterpretq_s32_p128(a);
}
-// CHECK-LABEL: define <2 x i64> @test_vreinterpretq_s64_p128(i128 %a) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vreinterpretq_s64_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <2 x i64>
// CHECK: ret <2 x i64> [[TMP0]]
int64x2_t test_vreinterpretq_s64_p128(poly128_t a) {
return vreinterpretq_s64_p128(a);
}
-// CHECK-LABEL: define <16 x i8> @test_vreinterpretq_u8_p128(i128 %a) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vreinterpretq_u8_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <16 x i8>
// CHECK: ret <16 x i8> [[TMP0]]
uint8x16_t test_vreinterpretq_u8_p128(poly128_t a) {
return vreinterpretq_u8_p128(a);
}
-// CHECK-LABEL: define <8 x i16> @test_vreinterpretq_u16_p128(i128 %a) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vreinterpretq_u16_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <8 x i16>
// CHECK: ret <8 x i16> [[TMP0]]
uint16x8_t test_vreinterpretq_u16_p128(poly128_t a) {
return vreinterpretq_u16_p128(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vreinterpretq_u32_p128(i128 %a) #0 {
+// CHECK-LABEL: define <4 x i32> @test_vreinterpretq_u32_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <4 x i32>
// CHECK: ret <4 x i32> [[TMP0]]
uint32x4_t test_vreinterpretq_u32_p128(poly128_t a) {
return vreinterpretq_u32_p128(a);
}
-// CHECK-LABEL: define <2 x i64> @test_vreinterpretq_u64_p128(i128 %a) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vreinterpretq_u64_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <2 x i64>
// CHECK: ret <2 x i64> [[TMP0]]
uint64x2_t test_vreinterpretq_u64_p128(poly128_t a) {
return vreinterpretq_u64_p128(a);
}
-// CHECK-LABEL: define <4 x float> @test_vreinterpretq_f32_p128(i128 %a) #0 {
+// CHECK-LABEL: define <4 x float> @test_vreinterpretq_f32_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <4 x float>
// CHECK: ret <4 x float> [[TMP0]]
float32x4_t test_vreinterpretq_f32_p128(poly128_t a) {
return vreinterpretq_f32_p128(a);
}
-// CHECK-LABEL: define <2 x double> @test_vreinterpretq_f64_p128(i128 %a) #0 {
+// CHECK-LABEL: define <2 x double> @test_vreinterpretq_f64_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <2 x double>
// CHECK: ret <2 x double> [[TMP0]]
float64x2_t test_vreinterpretq_f64_p128(poly128_t a) {
return vreinterpretq_f64_p128(a);
}
-// CHECK-LABEL: define <16 x i8> @test_vreinterpretq_p8_p128(i128 %a) #0 {
+// CHECK-LABEL: define <16 x i8> @test_vreinterpretq_p8_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <16 x i8>
// CHECK: ret <16 x i8> [[TMP0]]
poly8x16_t test_vreinterpretq_p8_p128(poly128_t a) {
return vreinterpretq_p8_p128(a);
}
-// CHECK-LABEL: define <8 x i16> @test_vreinterpretq_p16_p128(i128 %a) #0 {
+// CHECK-LABEL: define <8 x i16> @test_vreinterpretq_p16_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <8 x i16>
// CHECK: ret <8 x i16> [[TMP0]]
poly16x8_t test_vreinterpretq_p16_p128(poly128_t a) {
return vreinterpretq_p16_p128(a);
}
-// CHECK-LABEL: define <2 x i64> @test_vreinterpretq_p64_p128(i128 %a) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vreinterpretq_p64_p128(i128 %a) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i128 %a to <2 x i64>
// CHECK: ret <2 x i64> [[TMP0]]
poly64x2_t test_vreinterpretq_p64_p128(poly128_t a) {
diff --git a/test/CodeGen/aarch64-poly64.c b/test/CodeGen/aarch64-poly64.c
index b70e5f0765..cdf91699c9 100644
--- a/test/CodeGen/aarch64-poly64.c
+++ b/test/CodeGen/aarch64-poly64.c
@@ -14,7 +14,7 @@ uint64x1_t test_vceq_p64(poly64x1_t a, poly64x1_t b) {
return vceq_p64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vceqq_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vceqq_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[CMP_I:%.*]] = icmp eq <2 x i64> %a, %b
// CHECK: [[SEXT_I:%.*]] = sext <2 x i1> [[CMP_I]] to <2 x i64>
// CHECK: ret <2 x i64> [[SEXT_I]]
@@ -31,7 +31,7 @@ uint64x1_t test_vtst_p64(poly64x1_t a, poly64x1_t b) {
return vtst_p64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vtstq_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vtstq_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[TMP4:%.*]] = and <2 x i64> %a, %b
// CHECK: [[TMP5:%.*]] = icmp ne <2 x i64> [[TMP4]], zeroinitializer
// CHECK: [[VTST_I:%.*]] = sext <2 x i1> [[TMP5]] to <2 x i64>
@@ -50,7 +50,7 @@ poly64x1_t test_vbsl_p64(poly64x1_t a, poly64x1_t b, poly64x1_t c) {
return vbsl_p64(a, b, c);
}
-// CHECK-LABEL: define <2 x i64> @test_vbslq_p64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vbslq_p64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) #1 {
// CHECK: [[VBSL3_I:%.*]] = and <2 x i64> %a, %b
// CHECK: [[TMP3:%.*]] = xor <2 x i64> %a, <i64 -1, i64 -1>
// CHECK: [[VBSL4_I:%.*]] = and <2 x i64> [[TMP3]], %c
@@ -69,7 +69,7 @@ poly64_t test_vget_lane_p64(poly64x1_t v) {
return vget_lane_p64(v, 0);
}
-// CHECK-LABEL: define i64 @test_vgetq_lane_p64(<2 x i64> %v) #0 {
+// CHECK-LABEL: define i64 @test_vgetq_lane_p64(<2 x i64> %v) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %v to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
@@ -87,7 +87,7 @@ poly64x1_t test_vset_lane_p64(poly64_t a, poly64x1_t v) {
return vset_lane_p64(a, v, 0);
}
-// CHECK-LABEL: define <2 x i64> @test_vsetq_lane_p64(i64 %a, <2 x i64> %v) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vsetq_lane_p64(i64 %a, <2 x i64> %v) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %v to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VSET_LANE:%.*]] = insertelement <2 x i64> [[TMP1]], i64 %a, i32 1
@@ -109,7 +109,7 @@ poly64x1_t test_vcopy_lane_p64(poly64x1_t a, poly64x1_t b) {
}
-// CHECK-LABEL: define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <1 x i64> %b to <8 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
// CHECK: [[VGET_LANE:%.*]] = extractelement <1 x i64> [[TMP1]], i32 0
@@ -121,7 +121,7 @@ poly64x2_t test_vcopyq_lane_p64(poly64x2_t a, poly64x1_t b) {
return vcopyq_lane_p64(a, 1, b, 0);
}
-// CHECK-LABEL: define <2 x i64> @test_vcopyq_laneq_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vcopyq_laneq_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
// CHECK: [[VGETQ_LANE:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
@@ -146,7 +146,7 @@ poly64x1_t test_vcreate_p64(uint64_t a) {
poly64x1_t test_vdup_n_p64(poly64_t a) {
return vdup_n_p64(a);
}
-// CHECK-LABEL: define <2 x i64> @test_vdupq_n_p64(i64 %a) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vdupq_n_p64(i64 %a) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1
// CHECK: ret <2 x i64> [[VECINIT1_I]]
@@ -161,7 +161,7 @@ poly64x1_t test_vmov_n_p64(poly64_t a) {
return vmov_n_p64(a);
}
-// CHECK-LABEL: define <2 x i64> @test_vmovq_n_p64(i64 %a) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vmovq_n_p64(i64 %a) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1
// CHECK: ret <2 x i64> [[VECINIT1_I]]
@@ -176,21 +176,21 @@ poly64x1_t test_vdup_lane_p64(poly64x1_t vec) {
return vdup_lane_p64(vec, 0);
}
-// CHECK-LABEL: define <2 x i64> @test_vdupq_lane_p64(<1 x i64> %vec) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vdupq_lane_p64(<1 x i64> %vec) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <1 x i64> %vec, <1 x i64> %vec, <2 x i32> zeroinitializer
// CHECK: ret <2 x i64> [[SHUFFLE]]
poly64x2_t test_vdupq_lane_p64(poly64x1_t vec) {
return vdupq_lane_p64(vec, 0);
}
-// CHECK-LABEL: define <2 x i64> @test_vdupq_laneq_p64(<2 x i64> %vec) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vdupq_laneq_p64(<2 x i64> %vec) #1 {
// CHECK: [[SHUFFLE:%.*]] = shufflevector <2 x i64> %vec, <2 x i64> %vec, <2 x i32> <i32 1, i32 1>
// CHECK: ret <2 x i64> [[SHUFFLE]]
poly64x2_t test_vdupq_laneq_p64(poly64x2_t vec) {
return vdupq_laneq_p64(vec, 1);
}
-// CHECK-LABEL: define <2 x i64> @test_vcombine_p64(<1 x i64> %low, <1 x i64> %high) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vcombine_p64(<1 x i64> %low, <1 x i64> %high) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <1 x i64> %low, <1 x i64> %high, <2 x i32> <i32 0, i32 1>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vcombine_p64(poly64x1_t low, poly64x1_t high) {
@@ -206,7 +206,7 @@ poly64x1_t test_vld1_p64(poly64_t const * ptr) {
return vld1_p64(ptr);
}
-// CHECK-LABEL: define <2 x i64> @test_vld1q_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vld1q_p64(i64* %ptr) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %ptr to i8*
// CHECK: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to <2 x i64>*
// CHECK: [[TMP2:%.*]] = load <2 x i64>, <2 x i64>* [[TMP1]]
@@ -226,7 +226,7 @@ void test_vst1_p64(poly64_t * ptr, poly64x1_t val) {
return vst1_p64(ptr, val);
}
-// CHECK-LABEL: define void @test_vst1q_p64(i64* %ptr, <2 x i64> %val) #0 {
+// CHECK-LABEL: define void @test_vst1q_p64(i64* %ptr, <2 x i64> %val) #1 {
// CHECK: [[TMP0:%.*]] = bitcast i64* %ptr to i8*
// CHECK: [[TMP1:%.*]] = bitcast <2 x i64> %val to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast i8* [[TMP0]] to <2 x i64>*
@@ -237,7 +237,7 @@ void test_vst1q_p64(poly64_t * ptr, poly64x2_t val) {
return vst1q_p64(ptr, val);
}
-// CHECK-LABEL: define %struct.poly64x1x2_t @test_vld2_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define %struct.poly64x1x2_t @test_vld2_p64(i64* %ptr) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x1x2_t* [[__RET]] to i8*
@@ -255,7 +255,7 @@ poly64x1x2_t test_vld2_p64(poly64_t const * ptr) {
return vld2_p64(ptr);
}
-// CHECK-LABEL: define %struct.poly64x2x2_t @test_vld2q_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define %struct.poly64x2x2_t @test_vld2q_p64(i64* %ptr) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x2x2_t* [[__RET]] to i8*
@@ -273,7 +273,7 @@ poly64x2x2_t test_vld2q_p64(poly64_t const * ptr) {
return vld2q_p64(ptr);
}
-// CHECK-LABEL: define %struct.poly64x1x3_t @test_vld3_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define %struct.poly64x1x3_t @test_vld3_p64(i64* %ptr) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x1x3_t* [[__RET]] to i8*
@@ -291,7 +291,7 @@ poly64x1x3_t test_vld3_p64(poly64_t const * ptr) {
return vld3_p64(ptr);
}
-// CHECK-LABEL: define %struct.poly64x2x3_t @test_vld3q_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define %struct.poly64x2x3_t @test_vld3q_p64(i64* %ptr) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x2x3_t* [[__RET]] to i8*
@@ -309,7 +309,7 @@ poly64x2x3_t test_vld3q_p64(poly64_t const * ptr) {
return vld3q_p64(ptr);
}
-// CHECK-LABEL: define %struct.poly64x1x4_t @test_vld4_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define %struct.poly64x1x4_t @test_vld4_p64(i64* %ptr) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x1x4_t* [[__RET]] to i8*
@@ -327,7 +327,7 @@ poly64x1x4_t test_vld4_p64(poly64_t const * ptr) {
return vld4_p64(ptr);
}
-// CHECK-LABEL: define %struct.poly64x2x4_t @test_vld4q_p64(i64* %ptr) #0 {
+// CHECK-LABEL: define %struct.poly64x2x4_t @test_vld4q_p64(i64* %ptr) #2 {
// CHECK: [[RETVAL:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[__RET:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[TMP0:%.*]] = bitcast %struct.poly64x2x4_t* [[__RET]] to i8*
@@ -345,7 +345,7 @@ poly64x2x4_t test_vld4q_p64(poly64_t const * ptr) {
return vld4q_p64(ptr);
}
-// CHECK-LABEL: define void @test_vst2_p64(i64* %ptr, [2 x <1 x i64>] %val.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2_p64(i64* %ptr, [2 x <1 x i64>] %val.coerce) #2 {
// CHECK: [[VAL:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x2_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x1x2_t, %struct.poly64x1x2_t* [[VAL]], i32 0, i32 0
@@ -370,7 +370,7 @@ void test_vst2_p64(poly64_t * ptr, poly64x1x2_t val) {
return vst2_p64(ptr, val);
}
-// CHECK-LABEL: define void @test_vst2q_p64(i64* %ptr, [2 x <2 x i64>] %val.coerce) #0 {
+// CHECK-LABEL: define void @test_vst2q_p64(i64* %ptr, [2 x <2 x i64>] %val.coerce) #2 {
// CHECK: [[VAL:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x2_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x2x2_t, %struct.poly64x2x2_t* [[VAL]], i32 0, i32 0
@@ -395,7 +395,7 @@ void test_vst2q_p64(poly64_t * ptr, poly64x2x2_t val) {
return vst2q_p64(ptr, val);
}
-// CHECK-LABEL: define void @test_vst3_p64(i64* %ptr, [3 x <1 x i64>] %val.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3_p64(i64* %ptr, [3 x <1 x i64>] %val.coerce) #2 {
// CHECK: [[VAL:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x3_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x1x3_t, %struct.poly64x1x3_t* [[VAL]], i32 0, i32 0
@@ -425,7 +425,7 @@ void test_vst3_p64(poly64_t * ptr, poly64x1x3_t val) {
return vst3_p64(ptr, val);
}
-// CHECK-LABEL: define void @test_vst3q_p64(i64* %ptr, [3 x <2 x i64>] %val.coerce) #0 {
+// CHECK-LABEL: define void @test_vst3q_p64(i64* %ptr, [3 x <2 x i64>] %val.coerce) #2 {
// CHECK: [[VAL:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x3_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x2x3_t, %struct.poly64x2x3_t* [[VAL]], i32 0, i32 0
@@ -455,7 +455,7 @@ void test_vst3q_p64(poly64_t * ptr, poly64x2x3_t val) {
return vst3q_p64(ptr, val);
}
-// CHECK-LABEL: define void @test_vst4_p64(i64* %ptr, [4 x <1 x i64>] %val.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4_p64(i64* %ptr, [4 x <1 x i64>] %val.coerce) #2 {
// CHECK: [[VAL:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x1x4_t, align 8
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x1x4_t, %struct.poly64x1x4_t* [[VAL]], i32 0, i32 0
@@ -490,7 +490,7 @@ void test_vst4_p64(poly64_t * ptr, poly64x1x4_t val) {
return vst4_p64(ptr, val);
}
-// CHECK-LABEL: define void @test_vst4q_p64(i64* %ptr, [4 x <2 x i64>] %val.coerce) #0 {
+// CHECK-LABEL: define void @test_vst4q_p64(i64* %ptr, [4 x <2 x i64>] %val.coerce) #2 {
// CHECK: [[VAL:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[__S1:%.*]] = alloca %struct.poly64x2x4_t, align 16
// CHECK: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.poly64x2x4_t, %struct.poly64x2x4_t* [[VAL]], i32 0, i32 0
@@ -537,7 +537,7 @@ poly64x1_t test_vext_p64(poly64x1_t a, poly64x1_t b) {
}
-// CHECK-LABEL: define <2 x i64> @test_vextq_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vextq_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
@@ -548,42 +548,42 @@ poly64x2_t test_vextq_p64(poly64x2_t a, poly64x2_t b) {
return vextq_p64(a, b, 1);
}
-// CHECK-LABEL: define <2 x i64> @test_vzip1q_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vzip1q_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vzip1q_p64(poly64x2_t a, poly64x2_t b) {
return vzip1q_p64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vzip2q_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vzip2q_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vzip2q_p64(poly64x2_t a, poly64x2_t b) {
return vzip2q_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vuzp1q_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vuzp1q_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vuzp1q_p64(poly64x2_t a, poly64x2_t b) {
return vuzp1q_p64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vuzp2q_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vuzp2q_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vuzp2q_p64(poly64x2_t a, poly64x2_t b) {
return vuzp2q_u64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vtrn1q_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vtrn1q_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vtrn1q_p64(poly64x2_t a, poly64x2_t b) {
return vtrn1q_p64(a, b);
}
-// CHECK-LABEL: define <2 x i64> @test_vtrn2q_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vtrn2q_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
// CHECK: ret <2 x i64> [[SHUFFLE_I]]
poly64x2_t test_vtrn2q_p64(poly64x2_t a, poly64x2_t b) {
@@ -601,7 +601,7 @@ poly64x1_t test_vsri_n_p64(poly64x1_t a, poly64x1_t b) {
return vsri_n_p64(a, b, 33);
}
-// CHECK-LABEL: define <2 x i64> @test_vsriq_n_p64(<2 x i64> %a, <2 x i64> %b) #0 {
+// CHECK-LABEL: define <2 x i64> @test_vsriq_n_p64(<2 x i64> %a, <2 x i64> %b) #1 {
// CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x i64> %b to <16 x i8>
// CHECK: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
@@ -612,3 +612,6 @@ poly64x2_t test_vsriq_n_p64(poly64x2_t a, poly64x2_t b) {
return vsriq_n_p64(a, b, 64);
}
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
+// CHECK: attributes #2 ={{.*}}"min-legal-vector-width"="0"
diff --git a/test/CodeGen/aarch64-sign-return-address.c b/test/CodeGen/aarch64-sign-return-address.c
index d656bc3d0c..d062685e40 100644
--- a/test/CodeGen/aarch64-sign-return-address.c
+++ b/test/CodeGen/aarch64-sign-return-address.c
@@ -1,14 +1,27 @@
-// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-NONE
-// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-PARTIAL
-// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-ALL
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK --check-prefix=NONE
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.2-a -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK --check-prefix=ALL --check-prefix=A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK --check-prefix=ALL --check-prefix=A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK --check-prefix=PARTIAL --check-prefix=A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK --check-prefix=ALL --check-prefix=A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.4-a -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK --check-prefix=ALL --check-prefix=A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK --check-prefix=PARTIAL --check-prefix=B-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf %s | FileCheck %s --check-prefix=CHECK --check-prefix=ALL --check-prefix=B-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.3-a -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
-// CHECK-NONE: @foo() #[[ATTR:[0-9]*]]
-// CHECK-NONE-NOT: attributes #[[ATTR]] = { {{.*}} "sign-return-address"={{.*}} }}
+// REQUIRES: aarch64-registered-target
-// CHECK-PARTIAL: @foo() #[[ATTR:[0-9]*]]
-// CHECK-PARTIAL: attributes #[[ATTR]] = { {{.*}} "sign-return-address"="non-leaf" {{.*}}}
+// CHECK: @foo() #[[ATTR:[0-9]*]]
+//
+// NONE-NOT: "sign-return-address"={{.*}}
-// CHECK-ALL: @foo() #[[ATTR:[0-9]*]]
-// CHECK-ALL: attributes #[[ATTR]] = { {{.*}} "sign-return-address"="all" {{.*}} }
+// PARTIAL: "sign-return-address"="non-leaf"
+
+// ALL: "sign-return-address"="all"
+
+// BTE: "branch-target-enforcement"
+
+// A-KEY: "sign-return-address-key"="a_key"
+
+// B-KEY: "sign-return-address-key"="b_key"
void foo() {}
diff --git a/test/CodeGen/aarch64-vpcs.c b/test/CodeGen/aarch64-vpcs.c
new file mode 100644
index 0000000000..0fc2e96511
--- /dev/null
+++ b/test/CodeGen/aarch64-vpcs.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECKC
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -x c++ -o - %s | FileCheck %s -check-prefix=CHECKCXX
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -verify %s
+
+void __attribute__((aarch64_vector_pcs)) f(int *); // expected-warning {{calling convention 'aarch64_vector_pcs' ignored for this target}}
+
+// CHECKC: define void @g(
+// CHECKCXX: define void @_Z1gPi(
+void g(int *a) {
+
+// CHECKC: call aarch64_vector_pcs void @f(
+// CHECKCXX: call aarch64_vector_pcs void @_Z1fPi
+ f(a);
+}
+
+// CHECKC: declare aarch64_vector_pcs void @f(
+// CHECKCXX: declare aarch64_vector_pcs void @_Z1fPi
+
+void __attribute__((aarch64_vector_pcs)) h(int *a){ // expected-warning {{calling convention 'aarch64_vector_pcs' ignored for this target}}
+// CHECKC: define aarch64_vector_pcs void @h(
+// CHECKCXX: define aarch64_vector_pcs void @_Z1hPi(
+ f(a);
+}
diff --git a/test/CodeGen/adc-builtins.c b/test/CodeGen/adc-builtins.c
index feb6671742..036c25ceb7 100644
--- a/test/CodeGen/adc-builtins.c
+++ b/test/CodeGen/adc-builtins.c
@@ -5,7 +5,7 @@
unsigned char test_addcarry_u32(unsigned char __cf, unsigned int __x,
unsigned int __y, unsigned int *__p) {
// CHECK-LABEL: test_addcarry_u32
-// CHECK: [[ADC:%.*]] = call { i8, i32 } @llvm.x86.addcarry.u32
+// CHECK: [[ADC:%.*]] = call { i8, i32 } @llvm.x86.addcarry.32
// CHECK: [[DATA:%.*]] = extractvalue { i8, i32 } [[ADC]], 1
// CHECK: store i32 [[DATA]], i32* %{{.*}}
// CHECK: [[CF:%.*]] = extractvalue { i8, i32 } [[ADC]], 0
@@ -16,7 +16,7 @@ unsigned char test_addcarry_u64(unsigned char __cf, unsigned long long __x,
unsigned long long __y,
unsigned long long *__p) {
// CHECK-LABEL: test_addcarry_u64
-// CHECK: [[ADC:%.*]] = call { i8, i64 } @llvm.x86.addcarry.u64
+// CHECK: [[ADC:%.*]] = call { i8, i64 } @llvm.x86.addcarry.64
// CHECK: [[DATA:%.*]] = extractvalue { i8, i64 } [[ADC]], 1
// CHECK: store i64 [[DATA]], i64* %{{.*}}
// CHECK: [[CF:%.*]] = extractvalue { i8, i64 } [[ADC]], 0
@@ -26,7 +26,7 @@ unsigned char test_addcarry_u64(unsigned char __cf, unsigned long long __x,
unsigned char test_subborrow_u32(unsigned char __cf, unsigned int __x,
unsigned int __y, unsigned int *__p) {
// CHECK-LABEL: test_subborrow_u32
-// CHECK: [[SBB:%.*]] = call { i8, i32 } @llvm.x86.subborrow.u32
+// CHECK: [[SBB:%.*]] = call { i8, i32 } @llvm.x86.subborrow.32
// CHECK: [[DATA:%.*]] = extractvalue { i8, i32 } [[SBB]], 1
// CHECK: store i32 [[DATA]], i32* %{{.*}}
// CHECK: [[CF:%.*]] = extractvalue { i8, i32 } [[SBB]], 0
@@ -37,7 +37,7 @@ unsigned char test_subborrow_u64(unsigned char __cf, unsigned long long __x,
unsigned long long __y,
unsigned long long *__p) {
// CHECK-LABEL: test_subborrow_u64
-// CHECK: [[SBB:%.*]] = call { i8, i64 } @llvm.x86.subborrow.u64
+// CHECK: [[SBB:%.*]] = call { i8, i64 } @llvm.x86.subborrow.64
// CHECK: [[DATA:%.*]] = extractvalue { i8, i64 } [[SBB]], 1
// CHECK: store i64 [[DATA]], i64* %{{.*}}
// CHECK: [[CF:%.*]] = extractvalue { i8, i64 } [[SBB]], 0
diff --git a/test/CodeGen/address-sanitizer-and-array-cookie.cpp b/test/CodeGen/address-sanitizer-and-array-cookie.cpp
index e2267a10c2..821f1b032b 100644
--- a/test/CodeGen/address-sanitizer-and-array-cookie.cpp
+++ b/test/CodeGen/address-sanitizer-and-array-cookie.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - %s | FileCheck %s -check-prefix=PLAIN
// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - -fsanitize=address %s | FileCheck %s -check-prefix=ASAN
-// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - -fsanitize=address -fsanitize-address-poison-class-member-array-new-cookie %s | FileCheck %s -check-prefix=ASAN-POISON-ALL-NEW-ARRAY
+// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - -fsanitize=address -fsanitize-address-poison-custom-array-cookie %s | FileCheck %s -check-prefix=ASAN-POISON-ALL-NEW-ARRAY
typedef __typeof__(sizeof(0)) size_t;
namespace std {
diff --git a/test/CodeGen/adx-builtins.c b/test/CodeGen/adx-builtins.c
index 8fd95c005b..4047bbab06 100644
--- a/test/CodeGen/adx-builtins.c
+++ b/test/CodeGen/adx-builtins.c
@@ -5,7 +5,7 @@
unsigned char test_addcarryx_u32(unsigned char __cf, unsigned int __x,
unsigned int __y, unsigned int *__p) {
// CHECK-LABEL: test_addcarryx_u32
-// CHECK: [[ADC:%.*]] = call { i8, i32 } @llvm.x86.addcarryx.u32
+// CHECK: [[ADC:%.*]] = call { i8, i32 } @llvm.x86.addcarry.32
// CHECK: [[DATA:%.*]] = extractvalue { i8, i32 } [[ADC]], 1
// CHECK: store i32 [[DATA]], i32* %{{.*}}
// CHECK: [[CF:%.*]] = extractvalue { i8, i32 } [[ADC]], 0
@@ -16,7 +16,7 @@ unsigned char test_addcarryx_u64(unsigned char __cf, unsigned long long __x,
unsigned long long __y,
unsigned long long *__p) {
// CHECK-LABEL: test_addcarryx_u64
-// CHECK: [[ADC:%.*]] = call { i8, i64 } @llvm.x86.addcarryx.u64
+// CHECK: [[ADC:%.*]] = call { i8, i64 } @llvm.x86.addcarry.64
// CHECK: [[DATA:%.*]] = extractvalue { i8, i64 } [[ADC]], 1
// CHECK: store i64 [[DATA]], i64* %{{.*}}
// CHECK: [[CF:%.*]] = extractvalue { i8, i64 } [[ADC]], 0
diff --git a/test/CodeGen/arc/arguments.c b/test/CodeGen/arc/arguments.c
new file mode 100644
index 0000000000..fdc6037da7
--- /dev/null
+++ b/test/CodeGen/arc/arguments.c
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Basic argument tests for ARC.
+
+// CHECK: define void @f0(i32 inreg %i, i32 inreg %j, i64 inreg %k)
+void f0(int i, long j, long long k) {}
+
+typedef struct {
+ int aa;
+ int bb;
+} s1;
+// CHECK: define void @f1(i32 inreg %i.coerce0, i32 inreg %i.coerce1)
+void f1(s1 i) {}
+
+typedef struct {
+ char aa; char bb; char cc; char dd;
+} cs1;
+// CHECK: define void @cf1(i32 inreg %i.coerce)
+void cf1(cs1 i) {}
+
+typedef struct {
+ int cc;
+} s2;
+// CHECK: define void @f2(%struct.s2* noalias sret %agg.result)
+s2 f2() {
+ s2 foo;
+ return foo;
+}
+
+typedef struct {
+ int cc;
+ int dd;
+} s3;
+// CHECK: define void @f3(%struct.s3* noalias sret %agg.result)
+s3 f3() {
+ s3 foo;
+ return foo;
+}
+
+// CHECK: define void @f4(i64 inreg %i)
+void f4(long long i) {}
+
+// CHECK: define void @f5(i8 inreg signext %a, i16 inreg signext %b)
+void f5(signed char a, short b) {}
+
+// CHECK: define void @f6(i8 inreg zeroext %a, i16 inreg zeroext %b)
+void f6(unsigned char a, unsigned short b) {}
+
+enum my_enum {
+ ENUM1,
+ ENUM2,
+ ENUM3,
+};
+// Enums should be treated as the underlying i32.
+// CHECK: define void @f7(i32 inreg %a)
+void f7(enum my_enum a) {}
+
+enum my_big_enum {
+ ENUM4 = 0xFFFFFFFFFFFFFFFF,
+};
+// Big enums should be treated as the underlying i64.
+// CHECK: define void @f8(i64 inreg %a)
+void f8(enum my_big_enum a) {}
+
+union simple_union {
+ int a;
+ char b;
+};
+// Unions should be passed inreg.
+// CHECK: define void @f9(i32 inreg %s.coerce)
+void f9(union simple_union s) {}
+
+typedef struct {
+ int b4 : 4;
+ int b3 : 3;
+ int b8 : 8;
+} bitfield1;
+// Bitfields should be passed inreg.
+// CHECK: define void @f10(i32 inreg %bf1.coerce)
+void f10(bitfield1 bf1) {}
+
+// CHECK: define inreg { float, float } @cplx1(float inreg %r)
+_Complex float cplx1(float r) {
+ return r + 2.0fi;
+}
+
+// CHECK: define inreg { double, double } @cplx2(double inreg %r)
+_Complex double cplx2(double r) {
+ return r + 2.0i;
+}
+
+// CHECK: define inreg { i32, i32 } @cplx3(i32 inreg %r)
+_Complex int cplx3(int r) {
+ return r + 2i;
+}
+
+// CHECK: define inreg { i64, i64 } @cplx4(i64 inreg %r)
+_Complex long long cplx4(long long r) {
+ return r + 2i;
+}
+
+// CHECK: define inreg { i8, i8 } @cplx6(i8 inreg signext %r)
+_Complex signed char cplx6(signed char r) {
+ return r + 2i;
+}
+
+// CHECK: define inreg { i16, i16 } @cplx7(i16 inreg signext %r)
+_Complex short cplx7(short r) {
+ return r + 2i;
+}
+
+typedef struct {
+ int aa; int bb;
+} s8;
+
+typedef struct {
+ int aa; int bb; int cc; int dd;
+} s16;
+
+// Use 16-byte struct 2 times, gets 8 registers.
+void st2(s16 a, s16 b) {}
+// CHECK: define void @st2(i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %a.coerce2, i32 inreg %a.coerce3, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3)
+
+// Use 8-byte struct 3 times, gets 8 registers, 1 byval struct argument.
+void st3(s16 a, s16 b, s16 c) {}
+// CHECK: define void @st3(i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %a.coerce2, i32 inreg %a.coerce3, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)
+
+// 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval
+s16 st4(int x, s8 a, s16 b, s16 c) { return b; }
+// CHECK: define void @st4(%struct.s16* noalias sret %agg.result, i32 inreg %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)
+
+// 1 sret + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce)
+s16 st5(s8 a, s16 b, s16 c) { return b; }
+// CHECK: define void @st5(%struct.s16* noalias sret %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)
diff --git a/test/CodeGen/arc/struct-align.c b/test/CodeGen/arc/struct-align.c
new file mode 100644
index 0000000000..2aa7e7fc47
--- /dev/null
+++ b/test/CodeGen/arc/struct-align.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// 64-bit fields need only be 32-bit aligned for arc.
+
+typedef struct {
+ int aa;
+ double bb;
+} s1;
+
+// CHECK: define i32 @f1
+// CHECK: ret i32 12
+int f1() {
+ return sizeof(s1);
+}
+
+typedef struct {
+ int aa;
+ long long bb;
+} s2;
+// CHECK: define i32 @f2
+// CHECK: ret i32 12
+int f2() {
+ return sizeof(s2);
+}
+
diff --git a/test/CodeGen/arm-neon-fma.c b/test/CodeGen/arm-neon-fma.c
index 5f6737aaa7..0d85c6b756 100644
--- a/test/CodeGen/arm-neon-fma.c
+++ b/test/CodeGen/arm-neon-fma.c
@@ -8,14 +8,14 @@
#include <arm_neon.h>
// CHECK-LABEL: define <2 x float> @test_fma_order(<2 x float> %accum, <2 x float> %lhs, <2 x float> %rhs) #0 {
-// CHECK: [[TMP6:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %lhs, <2 x float> %rhs, <2 x float> %accum) #2
+// CHECK: [[TMP6:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %lhs, <2 x float> %rhs, <2 x float> %accum) #3
// CHECK: ret <2 x float> [[TMP6]]
float32x2_t test_fma_order(float32x2_t accum, float32x2_t lhs, float32x2_t rhs) {
return vfma_f32(accum, lhs, rhs);
}
-// CHECK-LABEL: define <4 x float> @test_fmaq_order(<4 x float> %accum, <4 x float> %lhs, <4 x float> %rhs) #0 {
-// CHECK: [[TMP6:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %lhs, <4 x float> %rhs, <4 x float> %accum) #2
+// CHECK-LABEL: define <4 x float> @test_fmaq_order(<4 x float> %accum, <4 x float> %lhs, <4 x float> %rhs) #1 {
+// CHECK: [[TMP6:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %lhs, <4 x float> %rhs, <4 x float> %accum) #3
// CHECK: ret <4 x float> [[TMP6]]
float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) {
return vfmaq_f32(accum, lhs, rhs);
@@ -32,7 +32,7 @@ float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) {
return vfma_n_f32(a, b, n);
}
-// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #0 {
+// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #1 {
// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %n, i32 0
// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %n, i32 1
// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %n, i32 2
@@ -44,3 +44,6 @@ float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) {
float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) {
return vfmaq_n_f32(a, b, n);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/arm-neon-numeric-maxmin.c b/test/CodeGen/arm-neon-numeric-maxmin.c
index d4f5674cd9..e844de7c81 100644
--- a/test/CodeGen/arm-neon-numeric-maxmin.c
+++ b/test/CodeGen/arm-neon-numeric-maxmin.c
@@ -3,29 +3,32 @@
#include <arm_neon.h>
// CHECK-LABEL: define <2 x float> @test_vmaxnm_f32(<2 x float> %a, <2 x float> %b) #0 {
-// CHECK: [[VMAXNM_V2_I:%.*]] = call <2 x float> @llvm.arm.neon.vmaxnm.v2f32(<2 x float> %a, <2 x float> %b) #2
+// CHECK: [[VMAXNM_V2_I:%.*]] = call <2 x float> @llvm.arm.neon.vmaxnm.v2f32(<2 x float> %a, <2 x float> %b) #3
// CHECK: ret <2 x float> [[VMAXNM_V2_I]]
float32x2_t test_vmaxnm_f32(float32x2_t a, float32x2_t b) {
return vmaxnm_f32(a, b);
}
-// CHECK-LABEL: define <4 x float> @test_vmaxnmq_f32(<4 x float> %a, <4 x float> %b) #0 {
-// CHECK: [[VMAXNMQ_V2_I:%.*]] = call <4 x float> @llvm.arm.neon.vmaxnm.v4f32(<4 x float> %a, <4 x float> %b) #2
+// CHECK-LABEL: define <4 x float> @test_vmaxnmq_f32(<4 x float> %a, <4 x float> %b) #1 {
+// CHECK: [[VMAXNMQ_V2_I:%.*]] = call <4 x float> @llvm.arm.neon.vmaxnm.v4f32(<4 x float> %a, <4 x float> %b) #3
// CHECK: ret <4 x float> [[VMAXNMQ_V2_I]]
float32x4_t test_vmaxnmq_f32(float32x4_t a, float32x4_t b) {
return vmaxnmq_f32(a, b);
}
// CHECK-LABEL: define <2 x float> @test_vminnm_f32(<2 x float> %a, <2 x float> %b) #0 {
-// CHECK: [[VMINNM_V2_I:%.*]] = call <2 x float> @llvm.arm.neon.vminnm.v2f32(<2 x float> %a, <2 x float> %b) #2
+// CHECK: [[VMINNM_V2_I:%.*]] = call <2 x float> @llvm.arm.neon.vminnm.v2f32(<2 x float> %a, <2 x float> %b) #3
// CHECK: ret <2 x float> [[VMINNM_V2_I]]
float32x2_t test_vminnm_f32(float32x2_t a, float32x2_t b) {
return vminnm_f32(a, b);
}
-// CHECK-LABEL: define <4 x float> @test_vminnmq_f32(<4 x float> %a, <4 x float> %b) #0 {
-// CHECK: [[VMINNMQ_V2_I:%.*]] = call <4 x float> @llvm.arm.neon.vminnm.v4f32(<4 x float> %a, <4 x float> %b) #2
+// CHECK-LABEL: define <4 x float> @test_vminnmq_f32(<4 x float> %a, <4 x float> %b) #1 {
+// CHECK: [[VMINNMQ_V2_I:%.*]] = call <4 x float> @llvm.arm.neon.vminnm.v4f32(<4 x float> %a, <4 x float> %b) #3
// CHECK: ret <4 x float> [[VMINNMQ_V2_I]]
float32x4_t test_vminnmq_f32(float32x4_t a, float32x4_t b) {
return vminnmq_f32(a, b);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/arm-neon-vcvtX.c b/test/CodeGen/arm-neon-vcvtX.c
index 43d48a0a4f..627c455d21 100644
--- a/test/CodeGen/arm-neon-vcvtX.c
+++ b/test/CodeGen/arm-neon-vcvtX.c
@@ -3,113 +3,116 @@
#include <arm_neon.h>
// CHECK-LABEL: define <2 x i32> @test_vcvta_s32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTA_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtas.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTA_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtas.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTA_S32_V1_I]]
int32x2_t test_vcvta_s32_f32(float32x2_t a) {
return vcvta_s32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvta_u32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTA_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtau.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTA_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtau.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTA_U32_V1_I]]
uint32x2_t test_vcvta_u32_f32(float32x2_t a) {
return vcvta_u32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtaq_s32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTAQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtas.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtaq_s32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTAQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtas.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTAQ_S32_V1_I]]
int32x4_t test_vcvtaq_s32_f32(float32x4_t a) {
return vcvtaq_s32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtaq_u32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTAQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtau.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtaq_u32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTAQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtau.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTAQ_U32_V1_I]]
uint32x4_t test_vcvtaq_u32_f32(float32x4_t a) {
return vcvtaq_u32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvtn_s32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTN_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtns.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTN_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtns.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTN_S32_V1_I]]
int32x2_t test_vcvtn_s32_f32(float32x2_t a) {
return vcvtn_s32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvtn_u32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTN_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtnu.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTN_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtnu.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTN_U32_V1_I]]
uint32x2_t test_vcvtn_u32_f32(float32x2_t a) {
return vcvtn_u32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtnq_s32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTNQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtns.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtnq_s32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTNQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtns.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTNQ_S32_V1_I]]
int32x4_t test_vcvtnq_s32_f32(float32x4_t a) {
return vcvtnq_s32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtnq_u32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTNQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtnu.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtnq_u32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTNQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtnu.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTNQ_U32_V1_I]]
uint32x4_t test_vcvtnq_u32_f32(float32x4_t a) {
return vcvtnq_u32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvtp_s32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTP_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtps.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTP_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtps.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTP_S32_V1_I]]
int32x2_t test_vcvtp_s32_f32(float32x2_t a) {
return vcvtp_s32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvtp_u32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTP_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtpu.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTP_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtpu.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTP_U32_V1_I]]
uint32x2_t test_vcvtp_u32_f32(float32x2_t a) {
return vcvtp_u32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtpq_s32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTPQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtps.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtpq_s32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTPQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtps.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTPQ_S32_V1_I]]
int32x4_t test_vcvtpq_s32_f32(float32x4_t a) {
return vcvtpq_s32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtpq_u32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTPQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtpu.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtpq_u32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTPQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtpu.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTPQ_U32_V1_I]]
uint32x4_t test_vcvtpq_u32_f32(float32x4_t a) {
return vcvtpq_u32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvtm_s32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTM_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtms.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTM_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtms.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTM_S32_V1_I]]
int32x2_t test_vcvtm_s32_f32(float32x2_t a) {
return vcvtm_s32_f32(a);
}
// CHECK-LABEL: define <2 x i32> @test_vcvtm_u32_f32(<2 x float> %a) #0 {
-// CHECK: [[VCVTM_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtmu.v2i32.v2f32(<2 x float> %a) #2
+// CHECK: [[VCVTM_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtmu.v2i32.v2f32(<2 x float> %a) #3
// CHECK: ret <2 x i32> [[VCVTM_U32_V1_I]]
uint32x2_t test_vcvtm_u32_f32(float32x2_t a) {
return vcvtm_u32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtmq_s32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTMQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtms.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtmq_s32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTMQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtms.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTMQ_S32_V1_I]]
int32x4_t test_vcvtmq_s32_f32(float32x4_t a) {
return vcvtmq_s32_f32(a);
}
-// CHECK-LABEL: define <4 x i32> @test_vcvtmq_u32_f32(<4 x float> %a) #0 {
-// CHECK: [[VCVTMQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtmu.v4i32.v4f32(<4 x float> %a) #2
+// CHECK-LABEL: define <4 x i32> @test_vcvtmq_u32_f32(<4 x float> %a) #1 {
+// CHECK: [[VCVTMQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtmu.v4i32.v4f32(<4 x float> %a) #3
// CHECK: ret <4 x i32> [[VCVTMQ_U32_V1_I]]
uint32x4_t test_vcvtmq_u32_f32(float32x4_t a) {
return vcvtmq_u32_f32(a);
}
+
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="64"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="128"
diff --git a/test/CodeGen/arm64-microsoft-intrinsics.c b/test/CodeGen/arm64-microsoft-intrinsics.c
index 2dbf1f9ea0..eeb09e8972 100644
--- a/test/CodeGen/arm64-microsoft-intrinsics.c
+++ b/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -4,6 +4,16 @@
// RUN: not %clang_cc1 -triple arm64-linux -Werror -S -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s -check-prefix CHECK-LINUX
+long test_InterlockedAdd(long volatile *Addend, long Value) {
+ return _InterlockedAdd(Addend, Value);
+}
+
+// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd(i32* %Addend, i32 %Value) {{.*}} {
+// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add i32* %1, i32 %2 seq_cst
+// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2
+// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]]
+// CHECK-LINUX: error: implicit declaration of function '_InterlockedAdd'
+
void check__dmb(void) {
__dmb(0);
}
@@ -59,3 +69,22 @@ void check__sevl(void) {
// CHECK-MSVC: @llvm.aarch64.hint(i32 5)
// CHECK-LINUX: error: implicit declaration of function '__sevl'
+
+void check_ReadWriteBarrier() {
+ _ReadWriteBarrier();
+}
+
+// CHECK-MSVC: fence syncscope("singlethread")
+// CHECK-LINUX: error: implicit declaration of function '_ReadWriteBarrier'
+
+unsigned __int64 check__getReg() {
+ unsigned volatile __int64 reg;
+ reg = __getReg(18);
+ reg = __getReg(31);
+ return reg;
+}
+
+// CHECK-MSVC: call i64 @llvm.read_register.i64(metadata ![[MD2:.*]])
+// CHECK-MSVC: call i64 @llvm.read_register.i64(metadata ![[MD3:.*]])
+// CHECK-MSVC: ![[MD2]] = !{!"x18"}
+// CHECK-MSVC: ![[MD3]] = !{!"sp"}
diff --git a/test/CodeGen/arm64-microsoft-status-reg.cpp b/test/CodeGen/arm64-microsoft-status-reg.cpp
new file mode 100644
index 0000000000..eb59bae50f
--- /dev/null
+++ b/test/CodeGen/arm64-microsoft-status-reg.cpp
@@ -0,0 +1,119 @@
+// REQUIRES: aarch64-registered-target
+
+// RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -emit-llvm -S \
+// RUN: -o - %s | FileCheck %s -check-prefix CHECK-ASM
+
+// RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -emit-llvm \
+// RUN: -o - %s | FileCheck %s -check-prefix CHECK-IR
+
+// From winnt.h
+#define ARM64_SYSREG(op0, op1, crn, crm, op2) \
+ ( ((op0 & 1) << 14) | \
+ ((op1 & 7) << 11) | \
+ ((crn & 15) << 7) | \
+ ((crm & 15) << 3) | \
+ ((op2 & 7) << 0) )
+
+#define ARM64_CNTVCT ARM64_SYSREG(3,3,14, 0,2) // Generic Timer counter register
+#define ARM64_PMCCNTR_EL0 ARM64_SYSREG(3,3, 9,13,0) // Cycle Count Register [CP15_PMCCNTR]
+#define ARM64_PMSELR_EL0 ARM64_SYSREG(3,3, 9,12,5) // Event Counter Selection Register [CP15_PMSELR]
+#define ARM64_PMXEVCNTR_EL0 ARM64_SYSREG(3,3, 9,13,2) // Event Count Register [CP15_PMXEVCNTR]
+#define ARM64_PMXEVCNTRn_EL0(n) ARM64_SYSREG(3,3,14, 8+((n)/8), (n)%8) // Direct Event Count Register [n/a]
+#define ARM64_TPIDR_EL0 ARM64_SYSREG(3,3,13, 0,2) // Thread ID Register, User Read/Write [CP15_TPIDRURW]
+#define ARM64_TPIDRRO_EL0 ARM64_SYSREG(3,3,13, 0,3) // Thread ID Register, User Read Only [CP15_TPIDRURO]
+#define ARM64_TPIDR_EL1 ARM64_SYSREG(3,0,13, 0,4) // Thread ID Register, Privileged Only [CP15_TPIDRPRW]
+
+void check_ReadWriteStatusReg(int v) {
+ int ret;
+ ret = _ReadStatusReg(ARM64_CNTVCT);
+// CHECK-ASM: mrs x8, CNTVCT_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD2:.*]])
+
+ ret = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+// CHECK-ASM: mrs x8, PMCCNTR_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD3:.*]])
+
+ ret = _ReadStatusReg(ARM64_PMSELR_EL0);
+// CHECK-ASM: mrs x8, PMSELR_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD4:.*]])
+
+ ret = _ReadStatusReg(ARM64_PMXEVCNTR_EL0);
+// CHECK-ASM: mrs x8, PMXEVCNTR_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD5:.*]])
+
+ ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(0));
+// CHECK-ASM: mrs x8, PMEVCNTR0_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD6:.*]])
+
+ ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(1));
+// CHECK-ASM: mrs x8, PMEVCNTR1_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD7:.*]])
+
+ ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(30));
+// CHECK-ASM: mrs x8, PMEVCNTR30_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD8:.*]])
+
+ ret = _ReadStatusReg(ARM64_TPIDR_EL0);
+// CHECK-ASM: mrs x8, TPIDR_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD9:.*]])
+
+ ret = _ReadStatusReg(ARM64_TPIDRRO_EL0);
+// CHECK-ASM: mrs x8, TPIDRRO_EL0
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD10:.*]])
+
+ ret = _ReadStatusReg(ARM64_TPIDR_EL1);
+// CHECK-ASM: mrs x8, TPIDR_EL1
+// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD11:.*]])
+
+
+ _WriteStatusReg(ARM64_CNTVCT, v);
+// CHECK-ASM: msr S3_3_C14_C0_2, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_PMCCNTR_EL0, v);
+// CHECK-ASM: msr PMCCNTR_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_PMSELR_EL0, v);
+// CHECK-ASM: msr PMSELR_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_PMXEVCNTR_EL0, v);
+// CHECK-ASM: msr PMXEVCNTR_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(0), v);
+// CHECK-ASM: msr PMEVCNTR0_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(1), v);
+// CHECK-ASM: msr PMEVCNTR1_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD7:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(30), v);
+// CHECK-ASM: msr PMEVCNTR30_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD8:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_TPIDR_EL0, v);
+// CHECK-ASM: msr TPIDR_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD9:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_TPIDRRO_EL0, v);
+// CHECK-ASM: msr TPIDRRO_EL0, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD10:.*]], i64 {{%.*}})
+
+ _WriteStatusReg(ARM64_TPIDR_EL1, v);
+// CHECK-ASM: msr TPIDR_EL1, x8
+// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD11:.*]], i64 {{%.*}})
+}
+
+// CHECK-IR: ![[MD2]] = !{!"3:3:14:0:2"}
+// CHECK-IR: ![[MD3]] = !{!"3:3:9:13:0"}
+// CHECK-IR: ![[MD4]] = !{!"3:3:9:12:5"}
+// CHECK-IR: ![[MD5]] = !{!"3:3:9:13:2"}
+// CHECK-IR: ![[MD6]] = !{!"3:3:14:8:0"}
+// CHECK-IR: ![[MD7]] = !{!"3:3:14:8:1"}
+// CHECK-IR: ![[MD8]] = !{!"3:3:14:11:6"}
+// CHECK-IR: ![[MD9]] = !{!"3:3:13:0:2"}
+// CHECK-IR: ![[MD10]] = !{!"3:3:13:0:3"}
+// CHECK-IR: ![[MD11]] = !{!"3:0:13:0:4"}
diff --git a/test/CodeGen/arm64_vdupq_n_f64.c b/test/CodeGen/arm64_vdupq_n_f64.c
index e9e814e92a..24c57c4f0d 100644
--- a/test/CodeGen/arm64_vdupq_n_f64.c
+++ b/test/CodeGen/arm64_vdupq_n_f64.c
@@ -44,7 +44,7 @@ float64x2_t test_vmovq_n_f64(float64_t w) {
return vmovq_n_f64(w);
}
-// CHECK-LABEL: define <4 x half> @test_vmov_n_f16(half* %a1) #0 {
+// CHECK-LABEL: define <4 x half> @test_vmov_n_f16(half* %a1) #1 {
// CHECK: [[TMP0:%.*]] = load half, half* %a1, align 2
// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP0]], i32 0
// CHECK: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP0]], i32 1
@@ -76,3 +76,5 @@ float16x8_t test_vmovq_n_f16(float16_t *a1) {
return vmovq_n_f16(*a1);
}
+// CHECK: attributes #0 ={{.*}}"min-legal-vector-width"="128"
+// CHECK: attributes #1 ={{.*}}"min-legal-vector-width"="64"
diff --git a/test/CodeGen/asan-globals-odr.cpp b/test/CodeGen/asan-globals-odr.cpp
new file mode 100644
index 0000000000..4a148c3ce3
--- /dev/null
+++ b/test/CodeGen/asan-globals-odr.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR0,GLOB_VAR,ALIAS0
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR1,GLOB_ALIAS_INDICATOR,ALIAS1
+// RUN: %clang_cc1 -fsanitize=address -fno-sanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR0,GLOB_VAR,ALIAS0
+// RUN: %clang_cc1 -fsanitize=address -fno-sanitize-address-use-odr-indicator -fsanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR1,GLOB_ALIAS_INDICATOR,ALIAS1
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-use-odr-indicator -fno-sanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR0,GLOB_VAR,ALIAS0
+
+// No alias on Windows but indicators should work.
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,GLOB_VAR,ALIAS0
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,INDICATOR1,GLOB_VAR_INDICATOR,ALIAS0
+
+int global;
+
+int main() {
+ return global;
+}
+
+// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [60 x i8] } zeroinitializer, align 32
+
+// INDICATOR0-NOT: __odr_asan_gen
+// INDICATOR1: [[ODR:@.*__odr_asan_gen_.*global.*]] = global i8 0, align 1
+
+// GLOB_VAR: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 0 }]
+// GLOB_VAR_INDICATOR: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 ptrtoint (i8* [[ODR]] to i64) }]
+// GLOB_ALIAS_INDICATOR: @0 = internal global {{.*}} @1 to i64), {{.*}}, i64 ptrtoint (i8* [[ODR]] to i64) }]
+
+// ALIAS0-NOT: private alias
+// ALIAS1: @1 = private alias {{.*}} [[VAR]]
+
+// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
+// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
diff --git a/test/CodeGen/asan-static-odr.cpp b/test/CodeGen/asan-static-odr.cpp
new file mode 100644
index 0000000000..6b23b62e16
--- /dev/null
+++ b/test/CodeGen/asan-static-odr.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,ALIAS1
+
+// No alias on Windows but indicators should work.
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,ALIAS0
+
+static int global;
+
+int main() {
+ return global;
+}
+
+// CHECK-NOT: __odr_asan_gen
+// CHECK-NOT: private alias
+// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [60 x i8] } zeroinitializer, align 32
+// CHECK: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 -1 }]
+// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
+// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
diff --git a/test/CodeGen/atomics-inlining.c b/test/CodeGen/atomics-inlining.c
index fc23c0b3f6..7ba3f7f59b 100644
--- a/test/CodeGen/atomics-inlining.c
+++ b/test/CodeGen/atomics-inlining.c
@@ -2,7 +2,10 @@
// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=PPC32
// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=PPC64
// RUN: %clang_cc1 -triple mipsel-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS32
+// RUN: %clang_cc1 -triple mipsisa32r6el-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS32
// RUN: %clang_cc1 -triple mips64el-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS64
+// RUN: %clang_cc1 -triple mips64el-linux-gnuabi64 -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS64
+// RUN: %clang_cc1 -triple mipsisa64r6el-linux-gnuabi64 -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS64
// RUN: %clang_cc1 -triple sparc-unknown-eabi -emit-llvm %s -o - | FileCheck %s -check-prefix=SPARCV8 -check-prefix=SPARC
// RUN: %clang_cc1 -triple sparcv9-unknown-eabi -emit-llvm %s -o - | FileCheck %s -check-prefix=SPARCV9 -check-prefix=SPARC
diff --git a/test/CodeGen/attr-cpuspecific.c b/test/CodeGen/attr-cpuspecific.c
index 1b98b5dc96..d6c99648cb 100644
--- a/test/CodeGen/attr-cpuspecific.c
+++ b/test/CodeGen/attr-cpuspecific.c
@@ -1,100 +1,258 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WINDOWS
+#ifdef _WIN64
+#define ATTR(X) __declspec(X)
+#else
+#define ATTR(X) __attribute__((X))
+#endif // _MSC_VER
// Each called version should have an IFunc.
-// CHECK: @SingleVersion.ifunc = ifunc void (), void ()* ()* @SingleVersion.resolver
-// CHECK: @TwoVersions.ifunc = ifunc void (), void ()* ()* @TwoVersions.resolver
-// CHECK: @TwoVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @TwoVersionsSameAttr.resolver
-// CHECK: @ThreeVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @ThreeVersionsSameAttr.resolver
+// LINUX: @SingleVersion.ifunc = ifunc void (), void ()* ()* @SingleVersion.resolver
+// LINUX: @TwoVersions.ifunc = ifunc void (), void ()* ()* @TwoVersions.resolver
+// LINUX: @TwoVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @TwoVersionsSameAttr.resolver
+// LINUX: @ThreeVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @ThreeVersionsSameAttr.resolver
-__attribute__((cpu_specific(ivybridge)))
+ATTR(cpu_specific(ivybridge))
void SingleVersion(void){}
-// CHECK: define void @SingleVersion.S() #[[S:[0-9]+]]
+// LINUX: define void @SingleVersion.S() #[[S:[0-9]+]]
+// WINDOWS: define dso_local void @SingleVersion.S() #[[S:[0-9]+]]
-__attribute__((cpu_specific(ivybridge)))
+ATTR(cpu_specific(ivybridge))
void NotCalled(void){}
-// CHECK: define void @NotCalled.S() #[[S]]
+// LINUX: define void @NotCalled.S() #[[S]]
+// WINDOWS: define dso_local void @NotCalled.S() #[[S:[0-9]+]]
-// Done before any of the implementations.
-__attribute__((cpu_dispatch(ivybridge, knl)))
+// Done before any of the implementations. Also has an undecorated forward
+// declaration.
void TwoVersions(void);
-// CHECK: define void ()* @TwoVersions.resolver()
-// CHECK: call void @__cpu_indicator_init
-// CHECK: ret void ()* @TwoVersions.Z
-// CHECK: ret void ()* @TwoVersions.S
-// CHECK: call void @llvm.trap
-// CHECK: unreachable
-
-__attribute__((cpu_specific(ivybridge)))
+
+ATTR(cpu_dispatch(ivybridge, knl))
+void TwoVersions(void);
+// LINUX: define void ()* @TwoVersions.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret void ()* @TwoVersions.Z
+// LINUX: ret void ()* @TwoVersions.S
+// LINUX: call void @llvm.trap
+// LINUX: unreachable
+
+// WINDOWS: define dso_local void @TwoVersions()
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call void @TwoVersions.Z()
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @TwoVersions.S()
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @llvm.trap
+// WINDOWS: unreachable
+
+ATTR(cpu_specific(ivybridge))
void TwoVersions(void){}
-// CHECK: define void @TwoVersions.S() #[[S]]
+// CHECK: define {{.*}}void @TwoVersions.S() #[[S]]
-__attribute__((cpu_specific(knl)))
+ATTR(cpu_specific(knl))
void TwoVersions(void){}
-// CHECK: define void @TwoVersions.Z() #[[K:[0-9]+]]
+// CHECK: define {{.*}}void @TwoVersions.Z() #[[K:[0-9]+]]
-__attribute__((cpu_specific(ivybridge, knl)))
+ATTR(cpu_specific(ivybridge, knl))
void TwoVersionsSameAttr(void){}
-// CHECK: define void @TwoVersionsSameAttr.S() #[[S]]
-// CHECK: define void @TwoVersionsSameAttr.Z() #[[K]]
+// CHECK: define {{.*}}void @TwoVersionsSameAttr.S() #[[S]]
+// CHECK: define {{.*}}void @TwoVersionsSameAttr.Z() #[[K]]
-__attribute__((cpu_specific(atom, ivybridge, knl)))
+ATTR(cpu_specific(atom, ivybridge, knl))
void ThreeVersionsSameAttr(void){}
-// CHECK: define void @ThreeVersionsSameAttr.O() #[[O:[0-9]+]]
-// CHECK: define void @ThreeVersionsSameAttr.S() #[[S]]
-// CHECK: define void @ThreeVersionsSameAttr.Z() #[[K]]
+// CHECK: define {{.*}}void @ThreeVersionsSameAttr.O() #[[O:[0-9]+]]
+// CHECK: define {{.*}}void @ThreeVersionsSameAttr.S() #[[S]]
+// CHECK: define {{.*}}void @ThreeVersionsSameAttr.Z() #[[K]]
void usages() {
SingleVersion();
- // CHECK: @SingleVersion.ifunc()
+ // LINUX: @SingleVersion.ifunc()
+ // WINDOWS: @SingleVersion()
TwoVersions();
- // CHECK: @TwoVersions.ifunc()
+ // LINUX: @TwoVersions.ifunc()
+ // WINDOWS: @TwoVersions()
TwoVersionsSameAttr();
- // CHECK: @TwoVersionsSameAttr.ifunc()
+ // LINUX: @TwoVersionsSameAttr.ifunc()
+ // WINDOWS: @TwoVersionsSameAttr()
ThreeVersionsSameAttr();
- // CHECK: @ThreeVersionsSameAttr.ifunc()
+ // LINUX: @ThreeVersionsSameAttr.ifunc()
+ // WINDOWS: @ThreeVersionsSameAttr()
}
// has an extra config to emit!
-__attribute__((cpu_dispatch(ivybridge, knl, atom)))
+ATTR(cpu_dispatch(ivybridge, knl, atom))
void TwoVersionsSameAttr(void);
-// CHECK: define void ()* @TwoVersionsSameAttr.resolver()
-// CHECK: ret void ()* @TwoVersionsSameAttr.Z
-// CHECK: ret void ()* @TwoVersionsSameAttr.S
-// CHECK: ret void ()* @TwoVersionsSameAttr.O
-// CHECK: call void @llvm.trap
-// CHECK: unreachable
-
-__attribute__((cpu_dispatch(atom, ivybridge, knl)))
+// LINUX: define void ()* @TwoVersionsSameAttr.resolver()
+// LINUX: ret void ()* @TwoVersionsSameAttr.Z
+// LINUX: ret void ()* @TwoVersionsSameAttr.S
+// LINUX: ret void ()* @TwoVersionsSameAttr.O
+// LINUX: call void @llvm.trap
+// LINUX: unreachable
+
+// WINDOWS: define dso_local void @TwoVersionsSameAttr()
+// WINDOWS: call void @TwoVersionsSameAttr.Z
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @TwoVersionsSameAttr.S
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @TwoVersionsSameAttr.O
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @llvm.trap
+// WINDOWS: unreachable
+
+ATTR(cpu_dispatch(atom, ivybridge, knl))
void ThreeVersionsSameAttr(void){}
-// CHECK: define void ()* @ThreeVersionsSameAttr.resolver()
-// CHECK: call void @__cpu_indicator_init
-// CHECK: ret void ()* @ThreeVersionsSameAttr.Z
-// CHECK: ret void ()* @ThreeVersionsSameAttr.S
-// CHECK: ret void ()* @ThreeVersionsSameAttr.O
-// CHECK: call void @llvm.trap
-// CHECK: unreachable
+// LINUX: define void ()* @ThreeVersionsSameAttr.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret void ()* @ThreeVersionsSameAttr.Z
+// LINUX: ret void ()* @ThreeVersionsSameAttr.S
+// LINUX: ret void ()* @ThreeVersionsSameAttr.O
+// LINUX: call void @llvm.trap
+// LINUX: unreachable
+
+// WINDOWS: define dso_local void @ThreeVersionsSameAttr()
+// WINDOWS: call void @__cpu_indicator_init
+// WINDOWS: call void @ThreeVersionsSameAttr.Z
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @ThreeVersionsSameAttr.S
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @ThreeVersionsSameAttr.O
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @llvm.trap
+// WINDOWS: unreachable
// No Cpu Specific options.
-__attribute__((cpu_dispatch(atom, ivybridge, knl)))
+ATTR(cpu_dispatch(atom, ivybridge, knl))
void NoSpecifics(void);
-// CHECK: define void ()* @NoSpecifics.resolver()
-// CHECK: call void @__cpu_indicator_init
-// CHECK: ret void ()* @NoSpecifics.Z
-// CHECK: ret void ()* @NoSpecifics.S
-// CHECK: ret void ()* @NoSpecifics.O
-// CHECK: call void @llvm.trap
-// CHECK: unreachable
-
-__attribute__((cpu_dispatch(atom, generic, ivybridge, knl)))
+// LINUX: define void ()* @NoSpecifics.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret void ()* @NoSpecifics.Z
+// LINUX: ret void ()* @NoSpecifics.S
+// LINUX: ret void ()* @NoSpecifics.O
+// LINUX: call void @llvm.trap
+// LINUX: unreachable
+
+// WINDOWS: define dso_local void @NoSpecifics()
+// WINDOWS: call void @__cpu_indicator_init
+// WINDOWS: call void @NoSpecifics.Z
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @NoSpecifics.S
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @NoSpecifics.O
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @llvm.trap
+// WINDOWS: unreachable
+
+ATTR(cpu_dispatch(atom, generic, ivybridge, knl))
void HasGeneric(void);
-// CHECK: define void ()* @HasGeneric.resolver()
-// CHECK: call void @__cpu_indicator_init
-// CHECK: ret void ()* @HasGeneric.Z
-// CHECK: ret void ()* @HasGeneric.S
-// CHECK: ret void ()* @HasGeneric.O
-// CHECK: ret void ()* @HasGeneric.A
-// CHECK-NOT: call void @llvm.trap
+// LINUX: define void ()* @HasGeneric.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret void ()* @HasGeneric.Z
+// LINUX: ret void ()* @HasGeneric.S
+// LINUX: ret void ()* @HasGeneric.O
+// LINUX: ret void ()* @HasGeneric.A
+// LINUX-NOT: call void @llvm.trap
+
+// WINDOWS: define dso_local void @HasGeneric()
+// WINDOWS: call void @__cpu_indicator_init
+// WINDOWS: call void @HasGeneric.Z
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @HasGeneric.S
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @HasGeneric.O
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @HasGeneric.A
+// WINDOWS-NEXT: ret void
+// WINDOWS-NOT: call void @llvm.trap
+
+ATTR(cpu_dispatch(atom, generic, ivybridge, knl))
+void HasParams(int i, double d);
+// LINUX: define void (i32, double)* @HasParams.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret void (i32, double)* @HasParams.Z
+// LINUX: ret void (i32, double)* @HasParams.S
+// LINUX: ret void (i32, double)* @HasParams.O
+// LINUX: ret void (i32, double)* @HasParams.A
+// LINUX-NOT: call void @llvm.trap
+
+// WINDOWS: define dso_local void @HasParams(i32, double)
+// WINDOWS: call void @__cpu_indicator_init
+// WINDOWS: call void @HasParams.Z(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @HasParams.S(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @HasParams.O(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @HasParams.A(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS-NOT: call void @llvm.trap
+
+ATTR(cpu_dispatch(atom, generic, ivybridge, knl))
+int HasParamsAndReturn(int i, double d);
+// LINUX: define i32 (i32, double)* @HasParamsAndReturn.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret i32 (i32, double)* @HasParamsAndReturn.Z
+// LINUX: ret i32 (i32, double)* @HasParamsAndReturn.S
+// LINUX: ret i32 (i32, double)* @HasParamsAndReturn.O
+// LINUX: ret i32 (i32, double)* @HasParamsAndReturn.A
+// LINUX-NOT: call void @llvm.trap
+
+// WINDOWS: define dso_local i32 @HasParamsAndReturn(i32, double)
+// WINDOWS: call void @__cpu_indicator_init
+// WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.Z(i32 %0, double %1)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.S(i32 %0, double %1)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.O(i32 %0, double %1)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.A(i32 %0, double %1)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS-NOT: call void @llvm.trap
+
+ATTR(cpu_dispatch(atom, generic, pentium))
+int GenericAndPentium(int i, double d);
+// LINUX: define i32 (i32, double)* @GenericAndPentium.resolver()
+// LINUX: call void @__cpu_indicator_init
+// LINUX: ret i32 (i32, double)* @GenericAndPentium.O
+// LINUX: ret i32 (i32, double)* @GenericAndPentium.B
+// LINUX-NOT: ret i32 (i32, double)* @GenericAndPentium.A
+// LINUX-NOT: call void @llvm.trap
+
+// WINDOWS: define dso_local i32 @GenericAndPentium(i32, double)
+// WINDOWS: call void @__cpu_indicator_init
+// WINDOWS: %[[RET:.+]] = musttail call i32 @GenericAndPentium.O(i32 %0, double %1)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:.+]] = musttail call i32 @GenericAndPentium.B(i32 %0, double %1)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS-NOT: call i32 @GenericAndPentium.A
+// WINDOWS-NOT: call void @llvm.trap
+
+ATTR(cpu_dispatch(atom, pentium))
+int DispatchFirst(void);
+// LINUX: define i32 ()* @DispatchFirst.resolver
+// LINUX: ret i32 ()* @DispatchFirst.O
+// LINUX: ret i32 ()* @DispatchFirst.B
+
+// WINDOWS: define dso_local i32 @DispatchFirst()
+// WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.O()
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.B()
+// WINDOWS-NEXT: ret i32 %[[RET]]
+
+ATTR(cpu_specific(atom))
+int DispatchFirst(void) {return 0;}
+// LINUX: define i32 @DispatchFirst.O
+// LINUX: ret i32 0
+
+// WINDOWS: define dso_local i32 @DispatchFirst.O()
+// WINDOWS: ret i32 0
+
+ATTR(cpu_specific(pentium))
+int DispatchFirst(void) {return 1;}
+// LINUX: define i32 @DispatchFirst.B
+// LINUX: ret i32 1
+
+// WINDOWS: define dso_local i32 @DispatchFirst.B
+// WINDOWS: ret i32 1
// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
diff --git a/test/CodeGen/attr-speculative-load-hardening.c b/test/CodeGen/attr-speculative-load-hardening.c
index ccbded44bb..97bccd0358 100644
--- a/test/CodeGen/attr-speculative-load-hardening.c
+++ b/test/CodeGen/attr-speculative-load-hardening.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -mspeculative-load-hardening -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=SLH
+// RUN: %clang -mno-speculative-load-hardening -S -emit-llvm %s -o - | FileCheck %s -check-prefix=NOSLH
//
// Check that we set the attribute on each function.
@@ -8,3 +9,7 @@ int test1() {
// SLH: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// NOSLH: @{{.*}}test1{{.*}}[[NOSLH:#[0-9]+]]
+
+// NOSLH-NOT: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGen/attr-speculative-load-hardening.cpp b/test/CodeGen/attr-speculative-load-hardening.cpp
new file mode 100644
index 0000000000..e2eb805cbb
--- /dev/null
+++ b/test/CodeGen/attr-speculative-load-hardening.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
+//
+// Check that we set the attribute on each function.
+
+[[clang::speculative_load_hardening]]
+int test1() {
+ return 42;
+}
+
+int __attribute__((speculative_load_hardening)) test2() {
+ return 42;
+}
+// CHECK1: @{{.*}}test1{{.*}}[[SLH1:#[0-9]+]]
+// CHECK1: attributes [[SLH1]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK2: @{{.*}}test2{{.*}}[[SLH2:#[0-9]+]]
+// CHECK2: attributes [[SLH2]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGen/attr-speculative-load-hardening.m b/test/CodeGen/attr-speculative-load-hardening.m
new file mode 100644
index 0000000000..2de945b974
--- /dev/null
+++ b/test/CodeGen/attr-speculative-load-hardening.m
@@ -0,0 +1,9 @@
+// RUN: %clang -emit-llvm %s -o - -S | FileCheck %s -check-prefix=SLH
+
+int main() __attribute__((speculative_load_hardening)) {
+ return 0;
+}
+
+// SLH: @{{.*}}main{{.*}}[[SLH:#[0-9]+]]
+
+// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGen/attr-target-mv-func-ptrs.c b/test/CodeGen/attr-target-mv-func-ptrs.c
index 5df9a927cf..d1ff80050c 100644
--- a/test/CodeGen/attr-target-mv-func-ptrs.c
+++ b/test/CodeGen/attr-target-mv-func-ptrs.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
int __attribute__((target("sse4.2"))) foo(int i) { return 0; }
int __attribute__((target("arch=sandybridge"))) foo(int);
int __attribute__((target("arch=ivybridge"))) foo(int i) {return 1;}
@@ -16,17 +17,31 @@ int bar() {
return Free(1) + Free(2);
}
-// CHECK: @foo.ifunc = ifunc i32 (i32), i32 (i32)* ()* @foo.resolver
-// CHECK: define i32 @foo.sse4.2(
-// CHECK: ret i32 0
-// CHECK: define i32 @foo.arch_ivybridge(
-// CHECK: ret i32 1
-// CHECK: define i32 @foo(
-// CHECK: ret i32 2
+// LINUX: @foo.ifunc = ifunc i32 (i32), i32 (i32)* ()* @foo.resolver
+// LINUX: define i32 @foo.sse4.2(
+// LINUX: ret i32 0
+// LINUX: define i32 @foo.arch_ivybridge(
+// LINUX: ret i32 1
+// LINUX: define i32 @foo(
+// LINUX: ret i32 2
-// CHECK: define i32 @bar()
-// CHECK: call void @func(i32 (i32)* @foo.ifunc)
-// CHECK: store i32 (i32)* @foo.ifunc
-// CHECK: store i32 (i32)* @foo.ifunc
+// WINDOWS: define dso_local i32 @foo.sse4.2(
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @foo.arch_ivybridge(
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @foo(
+// WINDOWS: ret i32 2
-// CHECK: declare i32 @foo.arch_sandybridge(
+// LINUX: define i32 @bar()
+// LINUX: call void @func(i32 (i32)* @foo.ifunc)
+// LINUX: store i32 (i32)* @foo.ifunc
+// LINUX: store i32 (i32)* @foo.ifunc
+
+// WINDOWS: define dso_local i32 @bar()
+// WINDOWS: call void @func(i32 (i32)* @foo.resolver)
+// WINDOWS: store i32 (i32)* @foo.resolver
+// WINDOWS: store i32 (i32)* @foo.resolver
+
+// LINUX: declare i32 @foo.arch_sandybridge(
+
+// WINDOWS: declare dso_local i32 @foo.arch_sandybridge(
diff --git a/test/CodeGen/attr-target-mv-va-args.c b/test/CodeGen/attr-target-mv-va-args.c
index b33f841dba..356b769140 100644
--- a/test/CodeGen/attr-target-mv-va-args.c
+++ b/test/CodeGen/attr-target-mv-va-args.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
int __attribute__((target("sse4.2"))) foo(int i, ...) { return 0; }
int __attribute__((target("arch=sandybridge"))) foo(int i, ...);
int __attribute__((target("arch=ivybridge"))) foo(int i, ...) {return 1;}
@@ -8,19 +9,37 @@ int bar() {
return foo(1, 'a', 1.1) + foo(2, 2.2, "asdf");
}
-// CHECK: @foo.ifunc = ifunc i32 (i32, ...), i32 (i32, ...)* ()* @foo.resolver
-// CHECK: define i32 @foo.sse4.2(i32 %i, ...)
-// CHECK: ret i32 0
-// CHECK: define i32 @foo.arch_ivybridge(i32 %i, ...)
-// CHECK: ret i32 1
-// CHECK: define i32 @foo(i32 %i, ...)
-// CHECK: ret i32 2
-// CHECK: define i32 @bar()
-// CHECK: call i32 (i32, ...) @foo.ifunc(i32 1, i32 97, double
-// CHECK: call i32 (i32, ...) @foo.ifunc(i32 2, double 2.2{{[0-9Ee+]+}}, i8* getelementptr inbounds
-// CHECK: define i32 (i32, ...)* @foo.resolver() comdat
-// CHECK: ret i32 (i32, ...)* @foo.arch_sandybridge
-// CHECK: ret i32 (i32, ...)* @foo.arch_ivybridge
-// CHECK: ret i32 (i32, ...)* @foo.sse4.2
-// CHECK: ret i32 (i32, ...)* @foo
-// CHECK: declare i32 @foo.arch_sandybridge(i32, ...)
+// LINUX: @foo.ifunc = ifunc i32 (i32, ...), i32 (i32, ...)* ()* @foo.resolver
+// LINUX: define i32 @foo.sse4.2(i32 %i, ...)
+// LINUX: ret i32 0
+// LINUX: define i32 @foo.arch_ivybridge(i32 %i, ...)
+// LINUX: ret i32 1
+// LINUX: define i32 @foo(i32 %i, ...)
+// LINUX: ret i32 2
+// LINUX: define i32 @bar()
+// LINUX: call i32 (i32, ...) @foo.ifunc(i32 1, i32 97, double
+// LINUX: call i32 (i32, ...) @foo.ifunc(i32 2, double 2.2{{[0-9Ee+]+}}, i8* getelementptr inbounds
+
+// LINUX: define i32 (i32, ...)* @foo.resolver() comdat
+// LINUX: ret i32 (i32, ...)* @foo.arch_sandybridge
+// LINUX: ret i32 (i32, ...)* @foo.arch_ivybridge
+// LINUX: ret i32 (i32, ...)* @foo.sse4.2
+// LINUX: ret i32 (i32, ...)* @foo
+// LINUX: declare i32 @foo.arch_sandybridge(i32, ...)
+
+// WINDOWS: define dso_local i32 @foo.sse4.2(i32 %i, ...)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @foo.arch_ivybridge(i32 %i, ...)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @foo(i32 %i, ...)
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @bar()
+// WINDOWS: call i32 (i32, ...) @foo.resolver(i32 1, i32 97, double
+// WINDOWS: call i32 (i32, ...) @foo.resolver(i32 2, double 2.2{{[0-9Ee+]+}}, i8* getelementptr inbounds
+
+// WINDOWS: define dso_local i32 @foo.resolver(i32, ...) comdat
+// WINDOWS: musttail call i32 (i32, ...) @foo.arch_sandybridge
+// WINDOWS: musttail call i32 (i32, ...) @foo.arch_ivybridge
+// WINDOWS: musttail call i32 (i32, ...) @foo.sse4.2
+// WINDOWS: musttail call i32 (i32, ...) @foo
+// WINDOWS: declare dso_local i32 @foo.arch_sandybridge(i32, ...)
diff --git a/test/CodeGen/attr-target-mv.c b/test/CodeGen/attr-target-mv.c
index 0085a154ce..363dea6a2f 100644
--- a/test/CodeGen/attr-target-mv.c
+++ b/test/CodeGen/attr-target-mv.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+
int __attribute__((target("sse4.2"))) foo(void) { return 0; }
int __attribute__((target("arch=sandybridge"))) foo(void);
int __attribute__((target("arch=ivybridge"))) foo(void) {return 1;}
@@ -25,67 +27,208 @@ void bar3() {
inline __attribute__((target("default"))) void foo_decls(void) {}
inline __attribute__((target("sse4.2"))) void foo_decls(void) {}
-inline __attribute__((target("default"))) void foo_multi(void) {}
-inline __attribute__((target("avx,sse4.2"))) void foo_multi(void) {}
-inline __attribute__((target("sse4.2,fma4"))) void foo_multi(void) {}
-inline __attribute__((target("arch=ivybridge,fma4,sse4.2"))) void foo_multi(void) {}
+inline __attribute__((target("default"))) void foo_multi(int i, double d) {}
+inline __attribute__((target("avx,sse4.2"))) void foo_multi(int i, double d) {}
+inline __attribute__((target("sse4.2,fma4"))) void foo_multi(int i, double d) {}
+inline __attribute__((target("arch=ivybridge,fma4,sse4.2"))) void foo_multi(int i, double d) {}
void bar4() {
- foo_multi();
+ foo_multi(1, 5.0);
}
-// CHECK: @foo.ifunc = ifunc i32 (), i32 ()* ()* @foo.resolver
-// CHECK: @foo_inline.ifunc = ifunc i32 (), i32 ()* ()* @foo_inline.resolver
-// CHECK: @foo_decls.ifunc = ifunc void (), void ()* ()* @foo_decls.resolver
-
-// CHECK: define i32 @foo.sse4.2()
-// CHECK: ret i32 0
-// CHECK: define i32 @foo.arch_ivybridge()
-// CHECK: ret i32 1
-// CHECK: define i32 @foo()
-// CHECK: ret i32 2
-// CHECK: define i32 @bar()
-// CHECK: call i32 @foo.ifunc()
-
-// CHECK: define i32 ()* @foo.resolver() comdat
-// CHECK: call void @__cpu_indicator_init()
-// CHECK: ret i32 ()* @foo.arch_sandybridge
-// CHECK: ret i32 ()* @foo.arch_ivybridge
-// CHECK: ret i32 ()* @foo.sse4.2
-// CHECK: ret i32 ()* @foo
-
-// CHECK: define i32 @bar2()
-// CHECK: call i32 @foo_inline.ifunc()
-
-// CHECK: define i32 ()* @foo_inline.resolver() comdat
-// CHECK: call void @__cpu_indicator_init()
-// CHECK: ret i32 ()* @foo_inline.arch_sandybridge
-// CHECK: ret i32 ()* @foo_inline.arch_ivybridge
-// CHECK: ret i32 ()* @foo_inline.sse4.2
-// CHECK: ret i32 ()* @foo_inline
-
-// CHECK: define void @bar3()
-// CHECK: call void @foo_decls.ifunc()
-
-// CHECK: define void ()* @foo_decls.resolver() comdat
-// CHECK: ret void ()* @foo_decls.sse4.2
-// CHECK: ret void ()* @foo_decls
-
-// CHECK: declare i32 @foo.arch_sandybridge()
-
-// CHECK: define available_externally i32 @foo_inline.sse4.2()
-// CHECK: ret i32 0
-
-// CHECK: declare i32 @foo_inline.arch_sandybridge()
-//
-// CHECK: define available_externally i32 @foo_inline.arch_ivybridge()
-// CHECK: ret i32 1
-// CHECK: define available_externally i32 @foo_inline()
-// CHECK: ret i32 2
-
-// CHECK: define available_externally void @foo_decls()
-// CHECK: define available_externally void @foo_decls.sse4.2()
-
-// CHECK: define available_externally void @foo_multi.avx_sse4.2()
-// CHECK: define available_externally void @foo_multi.fma4_sse4.2()
-// CHECK: define available_externally void @foo_multi.arch_ivybridge_fma4_sse4.2()
+int fwd_decl_default(void);
+int __attribute__((target("default"))) fwd_decl_default(void) { return 2; }
+
+int fwd_decl_avx(void);
+int __attribute__((target("avx"))) fwd_decl_avx(void) { return 2; }
+int __attribute__((target("default"))) fwd_decl_avx(void) { return 2; }
+
+void bar5() {
+ fwd_decl_default();
+ fwd_decl_avx();
+}
+// LINUX: @foo.ifunc = ifunc i32 (), i32 ()* ()* @foo.resolver
+// LINUX: @foo_inline.ifunc = ifunc i32 (), i32 ()* ()* @foo_inline.resolver
+// LINUX: @foo_decls.ifunc = ifunc void (), void ()* ()* @foo_decls.resolver
+// LINUX: @foo_multi.ifunc = ifunc void (i32, double), void (i32, double)* ()* @foo_multi.resolver
+// LINUX: @fwd_decl_default.ifunc = ifunc i32 (), i32 ()* ()* @fwd_decl_default.resolver
+// LINUX: @fwd_decl_avx.ifunc = ifunc i32 (), i32 ()* ()* @fwd_decl_avx.resolver
+
+// LINUX: define i32 @foo.sse4.2()
+// LINUX: ret i32 0
+// LINUX: define i32 @foo.arch_ivybridge()
+// LINUX: ret i32 1
+// LINUX: define i32 @foo()
+// LINUX: ret i32 2
+// LINUX: define i32 @bar()
+// LINUX: call i32 @foo.ifunc()
+
+// WINDOWS: define dso_local i32 @foo.sse4.2()
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @foo.arch_ivybridge()
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @foo()
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @bar()
+// WINDOWS: call i32 @foo.resolver()
+
+// LINUX: define i32 ()* @foo.resolver() comdat
+// LINUX: call void @__cpu_indicator_init()
+// LINUX: ret i32 ()* @foo.arch_sandybridge
+// LINUX: ret i32 ()* @foo.arch_ivybridge
+// LINUX: ret i32 ()* @foo.sse4.2
+// LINUX: ret i32 ()* @foo
+
+// WINDOWS: define dso_local i32 @foo.resolver() comdat
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @foo.arch_sandybridge
+// WINDOWS: call i32 @foo.arch_ivybridge
+// WINDOWS: call i32 @foo.sse4.2
+// WINDOWS: call i32 @foo
+
+// LINUX: define i32 @bar2()
+// LINUX: call i32 @foo_inline.ifunc()
+
+// WINDOWS: define dso_local i32 @bar2()
+// WINDOWS: call i32 @foo_inline.resolver()
+
+// LINUX: define i32 ()* @foo_inline.resolver() comdat
+// LINUX: call void @__cpu_indicator_init()
+// LINUX: ret i32 ()* @foo_inline.arch_sandybridge
+// LINUX: ret i32 ()* @foo_inline.arch_ivybridge
+// LINUX: ret i32 ()* @foo_inline.sse4.2
+// LINUX: ret i32 ()* @foo_inline
+
+// WINDOWS: define dso_local i32 @foo_inline.resolver() comdat
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @foo_inline.arch_sandybridge
+// WINDOWS: call i32 @foo_inline.arch_ivybridge
+// WINDOWS: call i32 @foo_inline.sse4.2
+// WINDOWS: call i32 @foo_inline
+
+// LINUX: define void @bar3()
+// LINUX: call void @foo_decls.ifunc()
+
+// WINDOWS: define dso_local void @bar3()
+// WINDOWS: call void @foo_decls.resolver()
+
+// LINUX: define void ()* @foo_decls.resolver() comdat
+// LINUX: ret void ()* @foo_decls.sse4.2
+// LINUX: ret void ()* @foo_decls
+
+// WINDOWS: define dso_local void @foo_decls.resolver() comdat
+// WINDOWS: call void @foo_decls.sse4.2
+// WINDOWS: call void @foo_decls
+
+// LINUX: define void @bar4()
+// LINUX: call void @foo_multi.ifunc(i32 1, double 5.{{[0+e]*}})
+
+// WINDOWS: define dso_local void @bar4()
+// WINDOWS: call void @foo_multi.resolver(i32 1, double 5.{{[0+e]*}})
+
+// LINUX: define void (i32, double)* @foo_multi.resolver() comdat
+// LINUX: and i32 %{{.*}}, 4352
+// LINUX: icmp eq i32 %{{.*}}, 4352
+// LINUX: ret void (i32, double)* @foo_multi.fma4_sse4.2
+// LINUX: icmp eq i32 %{{.*}}, 12
+// LINUX: and i32 %{{.*}}, 4352
+// LINUX: icmp eq i32 %{{.*}}, 4352
+// LINUX: ret void (i32, double)* @foo_multi.arch_ivybridge_fma4_sse4.2
+// LINUX: and i32 %{{.*}}, 768
+// LINUX: icmp eq i32 %{{.*}}, 768
+// LINUX: ret void (i32, double)* @foo_multi.avx_sse4.2
+// LINUX: ret void (i32, double)* @foo_multi
+
+// WINDOWS: define dso_local void @foo_multi.resolver(i32, double) comdat
+// WINDOWS: and i32 %{{.*}}, 4352
+// WINDOWS: icmp eq i32 %{{.*}}, 4352
+// WINDOWS: call void @foo_multi.fma4_sse4.2(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS: icmp eq i32 %{{.*}}, 12
+// WINDOWS: and i32 %{{.*}}, 4352
+// WINDOWS: icmp eq i32 %{{.*}}, 4352
+// WINDOWS: call void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS: and i32 %{{.*}}, 768
+// WINDOWS: icmp eq i32 %{{.*}}, 768
+// WINDOWS: call void @foo_multi.avx_sse4.2(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+// WINDOWS: call void @foo_multi(i32 %0, double %1)
+// WINDOWS-NEXT: ret void
+
+// LINUX: define i32 @fwd_decl_default()
+// LINUX: ret i32 2
+// LINUX: define i32 @fwd_decl_avx.avx()
+// LINUX: ret i32 2
+// LINUX: define i32 @fwd_decl_avx()
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @fwd_decl_default()
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @fwd_decl_avx.avx()
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @fwd_decl_avx()
+// WINDOWS: ret i32 2
+
+// LINUX: define void @bar5()
+// LINUX: call i32 @fwd_decl_default.ifunc()
+// LINUX: call i32 @fwd_decl_avx.ifunc()
+
+// WINDOWS: define dso_local void @bar5()
+// WINDOWS: call i32 @fwd_decl_default.resolver()
+// WINDOWS: call i32 @fwd_decl_avx.resolver()
+
+// LINUX: define i32 ()* @fwd_decl_default.resolver() comdat
+// LINUX: call void @__cpu_indicator_init()
+// LINUX: ret i32 ()* @fwd_decl_default
+// LINUX: define i32 ()* @fwd_decl_avx.resolver() comdat
+// LINUX: call void @__cpu_indicator_init()
+// LINUX: ret i32 ()* @fwd_decl_avx.avx
+// LINUX: ret i32 ()* @fwd_decl_avx
+
+// WINDOWS: define dso_local i32 @fwd_decl_default.resolver() comdat
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @fwd_decl_default
+// WINDOWS: define dso_local i32 @fwd_decl_avx.resolver() comdat
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @fwd_decl_avx.avx
+// WINDOWS: call i32 @fwd_decl_avx
+
+// LINUX: declare i32 @foo.arch_sandybridge()
+// WINDOWS: declare dso_local i32 @foo.arch_sandybridge()
+
+// LINUX: define linkonce i32 @foo_inline.sse4.2()
+// LINUX: ret i32 0
+
+// WINDOWS: define linkonce_odr dso_local i32 @foo_inline.sse4.2()
+// WINDOWS: ret i32 0
+
+// LINUX: declare i32 @foo_inline.arch_sandybridge()
+
+// WINDOWS: declare dso_local i32 @foo_inline.arch_sandybridge()
+
+// LINUX: define linkonce i32 @foo_inline.arch_ivybridge()
+// LINUX: ret i32 1
+// LINUX: define linkonce i32 @foo_inline()
+// LINUX: ret i32 2
+
+// WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_ivybridge()
+// WINDOWS: ret i32 1
+// WINDOWS: define linkonce_odr dso_local i32 @foo_inline()
+// WINDOWS: ret i32 2
+
+// LINUX: define linkonce void @foo_decls()
+// LINUX: define linkonce void @foo_decls.sse4.2()
+
+// WINDOWS: define linkonce_odr dso_local void @foo_decls()
+// WINDOWS: define linkonce_odr dso_local void @foo_decls.sse4.2()
+
+// LINUX: define linkonce void @foo_multi(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// LINUX: define linkonce void @foo_multi.avx_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// LINUX: define linkonce void @foo_multi.fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// LINUX: define linkonce void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
+
+// WINDOWS: define linkonce_odr dso_local void @foo_multi(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// WINDOWS: define linkonce_odr dso_local void @foo_multi.avx_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// WINDOWS: define linkonce_odr dso_local void @foo_multi.fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// WINDOWS: define linkonce_odr dso_local void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c
index 01476c9e89..d22bc7b5a3 100644
--- a/test/CodeGen/avx512bw-builtins.c
+++ b/test/CodeGen/avx512bw-builtins.c
@@ -2112,6 +2112,13 @@ __mmask32 test_mm512_kunpackw(__m512i __A, __m512i __B, __m512i __C, __m512i __D
return _mm512_mask_cmpneq_epu16_mask(_mm512_kunpackw(_mm512_cmpneq_epu16_mask(__B, __A),_mm512_cmpneq_epu16_mask(__C, __D)), __E, __F);
}
+__m512i test_mm512_loadu_epi16 (void *__P)
+{
+ // CHECK-LABEL: @test_mm512_loadu_epi16
+ // CHECK: load <8 x i64>, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_loadu_epi16 (__P);
+}
+
__m512i test_mm512_mask_loadu_epi16(__m512i __W, __mmask32 __U, void const *__P) {
// CHECK-LABEL: @test_mm512_mask_loadu_epi16
// CHECK: @llvm.masked.load.v32i16.p0v32i16(<32 x i16>* %{{.*}}, i32 1, <32 x i1> %{{.*}}, <32 x i16> %{{.*}})
@@ -2124,6 +2131,13 @@ __m512i test_mm512_maskz_loadu_epi16(__mmask32 __U, void const *__P) {
return _mm512_maskz_loadu_epi16(__U, __P);
}
+__m512i test_mm512_loadu_epi8 (void *__P)
+{
+ // CHECK-LABEL: @test_mm512_loadu_epi8
+ // CHECK: load <8 x i64>, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_loadu_epi8 (__P);
+}
+
__m512i test_mm512_mask_loadu_epi8(__m512i __W, __mmask64 __U, void const *__P) {
// CHECK-LABEL: @test_mm512_mask_loadu_epi8
// CHECK: @llvm.masked.load.v64i8.p0v64i8(<64 x i8>* %{{.*}}, i32 1, <64 x i1> %{{.*}}, <64 x i8> %{{.*}})
@@ -2135,11 +2149,19 @@ __m512i test_mm512_maskz_loadu_epi8(__mmask64 __U, void const *__P) {
// CHECK: @llvm.masked.load.v64i8.p0v64i8(<64 x i8>* %{{.*}}, i32 1, <64 x i1> %{{.*}}, <64 x i8> %{{.*}})
return _mm512_maskz_loadu_epi8(__U, __P);
}
+
+void test_mm512_storeu_epi16(void *__P, __m512i __A) {
+ // CHECK-LABEL: @test_mm512_storeu_epi16
+ // CHECK: store <8 x i64> %{{.*}}, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_storeu_epi16(__P, __A);
+}
+
void test_mm512_mask_storeu_epi16(void *__P, __mmask32 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_storeu_epi16
// CHECK: @llvm.masked.store.v32i16.p0v32i16(<32 x i16> %{{.*}}, <32 x i16>* %{{.*}}, i32 1, <32 x i1> %{{.*}})
- return _mm512_mask_storeu_epi16(__P, __U, __A);
+ return _mm512_mask_storeu_epi16(__P, __U, __A);
}
+
__mmask64 test_mm512_test_epi8_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_test_epi8_mask
// CHECK: and <16 x i32> %{{.*}}, %{{.*}}
@@ -2147,6 +2169,12 @@ __mmask64 test_mm512_test_epi8_mask(__m512i __A, __m512i __B) {
return _mm512_test_epi8_mask(__A, __B);
}
+void test_mm512_storeu_epi8(void *__P, __m512i __A) {
+ // CHECK-LABEL: @test_mm512_storeu_epi8
+ // CHECK: store <8 x i64> %{{.*}}, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_storeu_epi8(__P, __A);
+}
+
void test_mm512_mask_storeu_epi8(void *__P, __mmask64 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_storeu_epi8
// CHECK: @llvm.masked.store.v64i8.p0v64i8(<64 x i8> %{{.*}}, <64 x i8>* %{{.*}}, i32 1, <64 x i1> %{{.*}})
diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c
index 058591e636..b8efbddd62 100644
--- a/test/CodeGen/avx512f-builtins.c
+++ b/test/CodeGen/avx512f-builtins.c
@@ -254,12 +254,24 @@ void test_mm512_mask_store_pd(void *p, __m512d a, __mmask8 m)
_mm512_mask_store_pd(p, m, a);
}
+void test_mm512_storeu_epi32(void *__P, __m512i __A) {
+ // CHECK-LABEL: @test_mm512_storeu_epi32
+ // CHECK: store <8 x i64> %{{.*}}, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_storeu_epi32(__P, __A);
+}
+
void test_mm512_mask_storeu_epi32(void *__P, __mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_storeu_epi32
// CHECK: @llvm.masked.store.v16i32.p0v16i32(<16 x i32> %{{.*}}, <16 x i32>* %{{.*}}, i32 1, <16 x i1> %{{.*}})
return _mm512_mask_storeu_epi32(__P, __U, __A);
}
+void test_mm512_storeu_epi64(void *__P, __m512i __A) {
+ // CHECK-LABEL: @test_mm512_storeu_epi64
+ // CHECK: store <8 x i64> %{{.*}}, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_storeu_epi64(__P, __A);
+}
+
void test_mm512_mask_storeu_epi64(void *__P, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_storeu_epi64
// CHECK: @llvm.masked.store.v8i64.p0v8i64(<8 x i64> %{{.*}}, <8 x i64>* %{{.*}}, i32 1, <8 x i1> %{{.*}})
@@ -273,6 +285,13 @@ __m512i test_mm512_loadu_si512 (void *__P)
return _mm512_loadu_si512 ( __P);
}
+__m512i test_mm512_loadu_epi32 (void *__P)
+{
+ // CHECK-LABEL: @test_mm512_loadu_epi32
+ // CHECK: load <8 x i64>, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_loadu_epi32 (__P);
+}
+
__m512i test_mm512_mask_loadu_epi32 (__m512i __W, __mmask16 __U, void *__P)
{
// CHECK-LABEL: @test_mm512_mask_loadu_epi32
@@ -280,6 +299,20 @@ __m512i test_mm512_mask_loadu_epi32 (__m512i __W, __mmask16 __U, void *__P)
return _mm512_mask_loadu_epi32 (__W,__U, __P);
}
+__m512i test_mm512_maskz_loadu_epi32 (__mmask16 __U, void *__P)
+{
+ // CHECK-LABEL: @test_mm512_maskz_loadu_epi32
+ // CHECK: @llvm.masked.load.v16i32.p0v16i32(<16 x i32>* %{{.*}}, i32 1, <16 x i1> %{{.*}}, <16 x i32> %{{.*}})
+ return _mm512_maskz_loadu_epi32 (__U, __P);
+}
+
+__m512i test_mm512_loadu_epi64 (void *__P)
+{
+ // CHECK-LABEL: @test_mm512_loadu_epi64
+ // CHECK: load <8 x i64>, <8 x i64>* %{{.*}}, align 1{{$}}
+ return _mm512_loadu_epi64 (__P);
+}
+
__m512i test_mm512_mask_loadu_epi64 (__m512i __W, __mmask8 __U, void *__P)
{
// CHECK-LABEL: @test_mm512_mask_loadu_epi64
@@ -287,6 +320,13 @@ __m512i test_mm512_mask_loadu_epi64 (__m512i __W, __mmask8 __U, void *__P)
return _mm512_mask_loadu_epi64 (__W,__U, __P);
}
+__m512i test_mm512_maskz_loadu_epi64 (__mmask16 __U, void *__P)
+{
+ // CHECK-LABEL: @test_mm512_maskz_loadu_epi64
+ // CHECK: @llvm.masked.load.v8i64.p0v8i64(<8 x i64>* %{{.*}}, i32 1, <8 x i1> %{{.*}}, <8 x i64> %{{.*}})
+ return _mm512_maskz_loadu_epi64 (__U, __P);
+}
+
__m512 test_mm512_loadu_ps(void *p)
{
// CHECK-LABEL: @test_mm512_loadu_ps
diff --git a/test/CodeGen/avx512vl-builtins.c b/test/CodeGen/avx512vl-builtins.c
index 7e4e64381c..57931ca437 100644
--- a/test/CodeGen/avx512vl-builtins.c
+++ b/test/CodeGen/avx512vl-builtins.c
@@ -839,126 +839,182 @@ __m256i test_mm256_mask_mullo_epi32 (__m256i __W, __mmask8 __M, __m256i __A,
return _mm256_mask_mullo_epi32(__W, __M, __A, __B);
}
-__m256i test_mm256_mask_and_epi32 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_and_epi32 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_and_epi32
+ //CHECK: and <8 x i32> %{{.*}}, %{{.*}}
+ return _mm256_and_epi32(__A, __B);
+}
+
+__m256i test_mm256_mask_and_epi32 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_and_epi32
- //CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: and <8 x i32> %{{.*}}, %{{.*}}
+ //CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_and_epi32(__W, __U, __A, __B);
}
__m256i test_mm256_maskz_and_epi32 (__mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_maskz_and_epi32
- //CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: and <8 x i32> %{{.*}}, %{{.*}}
//CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_and_epi32(__U, __A, __B);
}
+__m128i test_mm_and_epi32 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_and_epi32
+ //CHECK: and <4 x i32> %{{.*}}, %{{.*}}
+ return _mm_and_epi32(__A, __B);
+}
+
__m128i test_mm_mask_and_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_and_epi32
- //CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: and <4 x i32> %{{.*}}, %{{.*}}
+ //CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_and_epi32(__W, __U, __A, __B);
}
__m128i test_mm_maskz_and_epi32 (__mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_maskz_and_epi32
- //CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: and <4 x i32> %{{.*}}, %{{.*}}
//CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_and_epi32(__U, __A, __B);
}
-__m256i test_mm256_mask_andnot_epi32 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_andnot_epi32 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_andnot_epi32
+ //CHECK: xor <8 x i32> %{{.*}}, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
+ //CHECK: and <8 x i32> %{{.*}}, %{{.*}}
+ return _mm256_andnot_epi32(__A, __B);
+}
+
+__m256i test_mm256_mask_andnot_epi32 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_andnot_epi32
- //CHECK: xor <4 x i64> %{{.*}}, <i64 -1, i64 -1, i64 -1, i64 -1>
- //CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <8 x i32> %{{.*}}, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
+ //CHECK: and <8 x i32> %{{.*}}, %{{.*}}
//CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_andnot_epi32(__W, __U, __A, __B);
}
__m256i test_mm256_maskz_andnot_epi32 (__mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_maskz_andnot_epi32
- //CHECK: xor <4 x i64> %{{.*}}, <i64 -1, i64 -1, i64 -1, i64 -1>
- //CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <8 x i32> %{{.*}}, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
+ //CHECK: and <8 x i32> %{{.*}}, %{{.*}}
//CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_andnot_epi32(__U, __A, __B);
}
-__m128i test_mm_mask_andnot_epi32 (__m128i __W, __mmask8 __U, __m128i __A,
- __m128i __B) {
+__m128i test_mm_andnot_epi32 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_andnot_epi32
+ //CHECK: xor <4 x i32> %{{.*}}, <i32 -1, i32 -1, i32 -1, i32 -1>
+ //CHECK: and <4 x i32> %{{.*}}, %{{.*}}
+ return _mm_andnot_epi32(__A, __B);
+}
+
+__m128i test_mm_mask_andnot_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_andnot_epi32
- //CHECK: xor <2 x i64> %{{.*}}, <i64 -1, i64 -1>
- //CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <4 x i32> %{{.*}}, <i32 -1, i32 -1, i32 -1, i32 -1>
+ //CHECK: and <4 x i32> %{{.*}}, %{{.*}}
//CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_andnot_epi32(__W, __U, __A, __B);
}
__m128i test_mm_maskz_andnot_epi32 (__mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_maskz_andnot_epi32
- //CHECK: xor <2 x i64> %{{.*}}, <i64 -1, i64 -1>
- //CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <4 x i32> %{{.*}}, <i32 -1, i32 -1, i32 -1, i32 -1>
+ //CHECK: and <4 x i32> %{{.*}}, %{{.*}}
//CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_andnot_epi32(__U, __A, __B);
}
-__m256i test_mm256_mask_or_epi32 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_or_epi32 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_or_epi32
+ //CHECK: or <8 x i32> %{{.*}}, %{{.*}}
+ return _mm256_or_epi32(__A, __B);
+}
+
+__m256i test_mm256_mask_or_epi32 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_or_epi32
- //CHECK: or <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: or <8 x i32> %{{.*}}, %{{.*}}
+ //CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_or_epi32(__W, __U, __A, __B);
}
__m256i test_mm256_maskz_or_epi32 (__mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_maskz_or_epi32
- //CHECK: or <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: or <8 x i32> %{{.*}}, %{{.*}}
//CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_or_epi32(__U, __A, __B);
}
- __m128i test_mm_mask_or_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
+__m128i test_mm_or_epi32 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_or_epi32
+ //CHECK: or <4 x i32> %{{.*}}, %{{.*}}
+ return _mm_or_epi32(__A, __B);
+}
+
+__m128i test_mm_mask_or_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_or_epi32
- //CHECK: or <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: or <4 x i32> %{{.*}}, %{{.*}}
+ //CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_or_epi32(__W, __U, __A, __B);
}
__m128i test_mm_maskz_or_epi32 (__mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_maskz_or_epi32
- //CHECK: or <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: or <4 x i32> %{{.*}}, %{{.*}}
//CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_or_epi32(__U, __A, __B);
}
-__m256i test_mm256_mask_xor_epi32 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_xor_epi32 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_xor_epi32
+ //CHECK: or <8 x i32> %{{.*}}, %{{.*}}
+ return _mm256_xor_epi32(__A, __B);
+}
+
+__m256i test_mm256_mask_xor_epi32 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_xor_epi32
- //CHECK: xor <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <8 x i32> %{{.*}}, %{{.*}}
+ //CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_xor_epi32(__W, __U, __A, __B);
}
__m256i test_mm256_maskz_xor_epi32 (__mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_maskz_xor_epi32
- //CHECK: xor <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <8 x i32> %{{.*}}, %{{.*}}
//CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_xor_epi32(__U, __A, __B);
}
-__m128i test_mm_mask_xor_epi32 (__m128i __W, __mmask8 __U, __m128i __A,
- __m128i __B) {
+__m128i test_mm_xor_epi32 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_xor_epi32
+ //CHECK: xor <4 x i32> %{{.*}}, %{{.*}}
+ return _mm_xor_epi32(__A, __B);
+}
+
+__m128i test_mm_mask_xor_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_xor_epi32
- //CHECK: xor <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <4 x i32> %{{.*}}, %{{.*}}
+ //CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_xor_epi32(__W, __U, __A, __B);
}
__m128i test_mm_maskz_xor_epi32 (__mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_maskz_xor_epi32
- //CHECK: xor <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: xor <4 x i32> %{{.*}}, %{{.*}}
//CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_xor_epi32(__U, __A, __B);
}
-__m256i test_mm256_mask_and_epi64 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_and_epi64 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_and_epi64
+ //CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ return _mm256_and_epi64(__A, __B);
+}
+
+__m256i test_mm256_mask_and_epi64 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_and_epi64
//CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_mask_and_epi64(__W, __U, __A, __B);
}
@@ -969,10 +1025,16 @@ __m256i test_mm256_maskz_and_epi64 (__mmask8 __U, __m256i __A, __m256i __B) {
return _mm256_maskz_and_epi64(__U, __A, __B);
}
-__m128i test_mm_mask_and_epi64 (__m128i __W, __mmask8 __U, __m128i __A,
- __m128i __B) {
+__m128i test_mm_and_epi64 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_and_epi64
+ //CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ return _mm_and_epi64(__A, __B);
+}
+
+__m128i test_mm_mask_and_epi64 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_and_epi64
//CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_mask_and_epi64(__W,__U, __A, __B);
}
@@ -983,8 +1045,14 @@ __m128i test_mm_maskz_and_epi64 (__mmask8 __U, __m128i __A, __m128i __B) {
return _mm_maskz_and_epi64(__U, __A, __B);
}
-__m256i test_mm256_mask_andnot_epi64 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_andnot_epi64 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_andnot_epi64
+ //CHECK: xor <4 x i64> %{{.*}}, <i64 -1, i64 -1, i64 -1, i64 -1>
+ //CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ return _mm256_andnot_epi64(__A, __B);
+}
+
+__m256i test_mm256_mask_andnot_epi64 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_andnot_epi64
//CHECK: xor <4 x i64> %{{.*}}, <i64 -1, i64 -1, i64 -1, i64 -1>
//CHECK: and <4 x i64> %{{.*}}, %{{.*}}
@@ -1000,8 +1068,14 @@ __m256i test_mm256_maskz_andnot_epi64 (__mmask8 __U, __m256i __A, __m256i __B) {
return _mm256_maskz_andnot_epi64(__U, __A, __B);
}
-__m128i test_mm_mask_andnot_epi64 (__m128i __W, __mmask8 __U, __m128i __A,
- __m128i __B) {
+__m128i test_mm_andnot_epi64 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_andnot_epi64
+ //CHECK: xor <2 x i64> %{{.*}}, <i64 -1, i64 -1>
+ //CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ return _mm_andnot_epi64(__A, __B);
+}
+
+__m128i test_mm_mask_andnot_epi64 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_andnot_epi64
//CHECK: xor <2 x i64> %{{.*}}, <i64 -1, i64 -1>
//CHECK: and <2 x i64> %{{.*}}, %{{.*}}
@@ -1017,10 +1091,16 @@ __m128i test_mm_maskz_andnot_epi64 (__mmask8 __U, __m128i __A, __m128i __B) {
return _mm_maskz_andnot_epi64(__U, __A, __B);
}
-__m256i test_mm256_mask_or_epi64 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_or_epi64 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_or_epi64
+ //CHECK: or <4 x i64> %{{.*}}, %{{.*}}
+ return _mm256_or_epi64(__A, __B);
+}
+
+__m256i test_mm256_mask_or_epi64 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_or_epi64
//CHECK: or <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_mask_or_epi64(__W,__U, __A, __B);
}
@@ -1031,9 +1111,16 @@ __m256i test_mm256_maskz_or_epi64 (__mmask8 __U, __m256i __A, __m256i __B) {
return _mm256_maskz_or_epi64(__U, __A, __B);
}
+__m128i test_mm_or_epi64 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_or_epi64
+ //CHECK: or <2 x i64> %{{.*}}, %{{.*}}
+ return _mm_or_epi64(__A, __B);
+}
+
__m128i test_mm_mask_or_epi64 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_or_epi64
//CHECK: or <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_mask_or_epi64(__W, __U, __A, __B);
}
@@ -1044,10 +1131,16 @@ __m128i test_mm_maskz_or_epi64 (__mmask8 __U, __m128i __A, __m128i __B) {
return _mm_maskz_or_epi64( __U, __A, __B);
}
-__m256i test_mm256_mask_xor_epi64 (__m256i __W, __mmask8 __U, __m256i __A,
- __m256i __B) {
+__m256i test_mm256_xor_epi64 (__m256i __A, __m256i __B) {
+ //CHECK-LABEL: @test_mm256_xor_epi64
+ //CHECK: xor <4 x i64> %{{.*}}, %{{.*}}
+ return _mm256_xor_epi64(__A, __B);
+}
+
+__m256i test_mm256_mask_xor_epi64 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
//CHECK-LABEL: @test_mm256_mask_xor_epi64
//CHECK: xor <4 x i64> %{{.*}}, %{{.*}}
+ //CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_mask_xor_epi64(__W,__U, __A, __B);
}
@@ -1058,9 +1151,16 @@ __m256i test_mm256_maskz_xor_epi64 (__mmask8 __U, __m256i __A, __m256i __B) {
return _mm256_maskz_xor_epi64(__U, __A, __B);
}
+__m128i test_mm_xor_epi64 (__m128i __A, __m128i __B) {
+ //CHECK-LABEL: @test_mm_xor_epi64
+ //CHECK: xor <2 x i64> %{{.*}}, %{{.*}}
+ return _mm_xor_epi64(__A, __B);
+}
+
__m128i test_mm_mask_xor_epi64 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
//CHECK-LABEL: @test_mm_mask_xor_epi64
//CHECK: xor <2 x i64> %{{.*}}, %{{.*}}
+ //CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_mask_xor_epi64(__W, __U, __A, __B);
}
@@ -6402,12 +6502,24 @@ __m256i test_mm256_maskz_srav_epi64(__mmask8 __U, __m256i __X, __m256i __Y) {
return _mm256_maskz_srav_epi64(__U, __X, __Y);
}
+void test_mm_store_epi32(void *__P, __m128i __A) {
+ // CHECK-LABEL: @test_mm_store_epi32
+ // CHECK: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}
+ return _mm_store_epi32(__P, __A);
+}
+
void test_mm_mask_store_epi32(void *__P, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_store_epi32
// CHECK: @llvm.masked.store.v4i32.p0v4i32(<4 x i32> %{{.*}}, <4 x i32>* %{{.}}, i32 16, <4 x i1> %{{.*}})
return _mm_mask_store_epi32(__P, __U, __A);
}
+void test_mm256_store_epi32(void *__P, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_store_epi32
+ // CHECK: store <4 x i64> %{{.*}}, <4 x i64>* %{{.*}}
+ return _mm256_store_epi32(__P, __A);
+}
+
void test_mm256_mask_store_epi32(void *__P, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_store_epi32
// CHECK: @llvm.masked.store.v8i32.p0v8i32(<8 x i32> %{{.*}}, <8 x i32>* %{{.}}, i32 32, <8 x i1> %{{.*}})
@@ -6462,6 +6574,12 @@ __m256i test_mm256_maskz_mov_epi64(__mmask8 __U, __m256i __A) {
return _mm256_maskz_mov_epi64(__U, __A);
}
+__m128i test_mm_load_epi32(void const *__P) {
+ // CHECK-LABEL: @test_mm_load_epi32
+ // CHECK: load <2 x i64>, <2 x i64>* %{{.*}}
+ return _mm_load_epi32(__P);
+}
+
__m128i test_mm_mask_load_epi32(__m128i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm_mask_load_epi32
// CHECK: @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %{{.*}}, i32 16, <4 x i1> %{{.*}}, <4 x i32> %{{.*}})
@@ -6474,6 +6592,12 @@ __m128i test_mm_maskz_load_epi32(__mmask8 __U, void const *__P) {
return _mm_maskz_load_epi32(__U, __P);
}
+__m256i test_mm256_load_epi32(void const *__P) {
+ // CHECK-LABEL: @test_mm256_load_epi32
+ // CHECK: load <4 x i64>, <4 x i64>* %{{.*}}
+ return _mm256_load_epi32(__P);
+}
+
__m256i test_mm256_mask_load_epi32(__m256i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm256_mask_load_epi32
// CHECK: @llvm.masked.load.v8i32.p0v8i32(<8 x i32>* %{{.*}}, i32 32, <8 x i1> %{{.*}}, <8 x i32> %{{.*}})
@@ -6486,6 +6610,12 @@ __m256i test_mm256_maskz_load_epi32(__mmask8 __U, void const *__P) {
return _mm256_maskz_load_epi32(__U, __P);
}
+__m128i test_mm_load_epi64(void const *__P) {
+ // CHECK-LABEL: @test_mm_load_epi64
+ // CHECK: load <2 x i64>, <2 x i64>* %{{.*}}
+ return _mm_load_epi64(__P);
+}
+
__m128i test_mm_mask_load_epi64(__m128i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm_mask_load_epi64
// CHECK: @llvm.masked.load.v2i64.p0v2i64(<2 x i64>* %{{.*}}, i32 16, <2 x i1> %{{.*}}, <2 x i64> %{{.*}})
@@ -6498,6 +6628,12 @@ __m128i test_mm_maskz_load_epi64(__mmask8 __U, void const *__P) {
return _mm_maskz_load_epi64(__U, __P);
}
+__m256i test_mm256_load_epi64(void const *__P) {
+ // CHECK-LABEL: @test_mm256_load_epi64
+ // CHECK: load <4 x i64>, <4 x i64>* %{{.*}}
+ return _mm256_load_epi64(__P);
+}
+
__m256i test_mm256_mask_load_epi64(__m256i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm256_mask_load_epi64
// CHECK: @llvm.masked.load.v4i64.p0v4i64(<4 x i64>* %{{.*}}, i32 32, <4 x i1> %{{.*}}, <4 x i64> %{{.*}})
@@ -6510,12 +6646,24 @@ __m256i test_mm256_maskz_load_epi64(__mmask8 __U, void const *__P) {
return _mm256_maskz_load_epi64(__U, __P);
}
+void test_mm_store_epi64(void *__P, __m128i __A) {
+ // CHECK-LABEL: @test_mm_store_epi64
+ // CHECK: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}
+ return _mm_store_epi64(__P, __A);
+}
+
void test_mm_mask_store_epi64(void *__P, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_store_epi64
// CHECK: @llvm.masked.store.v2i64.p0v2i64(<2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, i32 16, <2 x i1> %{{.*}})
return _mm_mask_store_epi64(__P, __U, __A);
}
+void test_mm256_store_epi64(void *__P, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_store_epi64
+ // CHECK: store <4 x i64> %{{.*}}, <4 x i64>* %{{.*}}
+ return _mm256_store_epi64(__P, __A);
+}
+
void test_mm256_mask_store_epi64(void *__P, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_store_epi64
// CHECK: @llvm.masked.store.v4i64.p0v4i64(<4 x i64> %{{.*}}, <4 x i64>* %{{.*}}, i32 32, <4 x i1> %{{.*}})
@@ -6760,6 +6908,12 @@ __m256 test_mm256_maskz_load_ps(__mmask8 __U, void const *__P) {
return _mm256_maskz_load_ps(__U, __P);
}
+__m128i test_mm_loadu_epi64(void const *__P) {
+ // CHECK-LABEL: @test_mm_loadu_epi64
+ // CHECK: load <2 x i64>, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_loadu_epi64(__P);
+}
+
__m128i test_mm_mask_loadu_epi64(__m128i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm_mask_loadu_epi64
// CHECK: @llvm.masked.load.v2i64.p0v2i64(<2 x i64>* %{{.*}}, i32 1, <2 x i1> %{{.*}}, <2 x i64> %{{.*}})
@@ -6772,6 +6926,12 @@ __m128i test_mm_maskz_loadu_epi64(__mmask8 __U, void const *__P) {
return _mm_maskz_loadu_epi64(__U, __P);
}
+__m256i test_mm256_loadu_epi64(void const *__P) {
+ // CHECK-LABEL: @test_mm256_loadu_epi64
+ // CHECK: load <4 x i64>, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_loadu_epi64(__P);
+}
+
__m256i test_mm256_mask_loadu_epi64(__m256i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm256_mask_loadu_epi64
// CHECK: @llvm.masked.load.v4i64.p0v4i64(<4 x i64>* %{{.*}}, i32 1, <4 x i1> %{{.*}}, <4 x i64> %{{.*}})
@@ -6784,6 +6944,12 @@ __m256i test_mm256_maskz_loadu_epi64(__mmask8 __U, void const *__P) {
return _mm256_maskz_loadu_epi64(__U, __P);
}
+__m128i test_mm_loadu_epi32(void const *__P) {
+ // CHECK-LABEL: @test_mm_loadu_epi32
+ // CHECK: load <2 x i64>, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_loadu_epi32(__P);
+}
+
__m128i test_mm_mask_loadu_epi32(__m128i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm_mask_loadu_epi32
// CHECK: @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %{{.*}}, i32 1, <4 x i1> %{{.*}}, <4 x i32> %{{.*}})
@@ -6796,6 +6962,12 @@ __m128i test_mm_maskz_loadu_epi32(__mmask8 __U, void const *__P) {
return _mm_maskz_loadu_epi32(__U, __P);
}
+__m256i test_mm256_loadu_epi32(void const *__P) {
+ // CHECK-LABEL: @test_mm256_loadu_epi32
+ // CHECK: load <4 x i64>, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_loadu_epi32(__P);
+}
+
__m256i test_mm256_mask_loadu_epi32(__m256i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm256_mask_loadu_epi32
// CHECK: @llvm.masked.load.v8i32.p0v8i32(<8 x i32>* %{{.*}}, i32 1, <8 x i1> %{{.*}}, <8 x i32> %{{.*}})
@@ -6880,24 +7052,48 @@ void test_mm256_mask_store_ps(void *__P, __mmask8 __U, __m256 __A) {
return _mm256_mask_store_ps(__P, __U, __A);
}
+void test_mm_storeu_epi64(void *__p, __m128i __a) {
+ // check-label: @test_mm_storeu_epi64
+ // check: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_storeu_epi64(__p, __a);
+}
+
void test_mm_mask_storeu_epi64(void *__P, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_storeu_epi64
// CHECK: @llvm.masked.store.v2i64.p0v2i64(<2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, i32 1, <2 x i1> %{{.*}})
return _mm_mask_storeu_epi64(__P, __U, __A);
}
+void test_mm256_storeu_epi64(void *__P, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_storeu_epi64
+ // CHECK: store <4 x i64> %{{.*}}, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_storeu_epi64(__P, __A);
+}
+
void test_mm256_mask_storeu_epi64(void *__P, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_storeu_epi64
// CHECK: @llvm.masked.store.v4i64.p0v4i64(<4 x i64> %{{.*}}, <4 x i64>* %{{.*}}, i32 1, <4 x i1> %{{.*}})
return _mm256_mask_storeu_epi64(__P, __U, __A);
}
+void test_mm_storeu_epi32(void *__P, __m128i __A) {
+ // CHECK-LABEL: @test_mm_storeu_epi32
+ // CHECK: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_storeu_epi32(__P, __A);
+}
+
void test_mm_mask_storeu_epi32(void *__P, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_storeu_epi32
// CHECK: @llvm.masked.store.v4i32.p0v4i32(<4 x i32> %{{.*}}, <4 x i32>* %{{.*}}, i32 1, <4 x i1> %{{.*}})
return _mm_mask_storeu_epi32(__P, __U, __A);
}
+void test_mm256_storeu_epi32(void *__P, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_storeu_epi32
+ // CHECK: store <4 x i64> %{{.*}}, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_storeu_epi32(__P, __A);
+}
+
void test_mm256_mask_storeu_epi32(void *__P, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_storeu_epi32
// CHECK: @llvm.masked.store.v8i32.p0v8i32(<8 x i32> %{{.*}}, <8 x i32>* %{{.*}}, i32 1, <8 x i1> %{{.*}})
diff --git a/test/CodeGen/avx512vlbw-builtins.c b/test/CodeGen/avx512vlbw-builtins.c
index 06fa935acc..06a48b5b27 100644
--- a/test/CodeGen/avx512vlbw-builtins.c
+++ b/test/CodeGen/avx512vlbw-builtins.c
@@ -2465,6 +2465,12 @@ __m256i test_mm256_maskz_mov_epi8(__mmask32 __U, __m256i __A) {
return _mm256_maskz_mov_epi8(__U, __A);
}
+__m128i test_mm_loadu_epi16(void const *__P) {
+ // CHECK-LABEL: @test_mm_loadu_epi16
+ // CHECK: load <2 x i64>, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_loadu_epi16(__P);
+}
+
__m128i test_mm_mask_loadu_epi16(__m128i __W, __mmask8 __U, void const *__P) {
// CHECK-LABEL: @test_mm_mask_loadu_epi16
// CHECK: @llvm.masked.load.v8i16.p0v8i16(<8 x i16>* %{{.*}}, i32 1, <8 x i1> %{{.*}}, <8 x i16> %{{.*}})
@@ -2477,6 +2483,12 @@ __m128i test_mm_maskz_loadu_epi16(__mmask8 __U, void const *__P) {
return _mm_maskz_loadu_epi16(__U, __P);
}
+__m256i test_mm256_loadu_epi16(void const *__P) {
+ // CHECK-LABEL: @test_mm256_loadu_epi16
+ // CHECK: load <4 x i64>, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_loadu_epi16(__P);
+}
+
__m256i test_mm256_mask_loadu_epi16(__m256i __W, __mmask16 __U, void const *__P) {
// CHECK-LABEL: @test_mm256_mask_loadu_epi16
// CHECK: @llvm.masked.load.v16i16.p0v16i16(<16 x i16>* %{{.*}}, i32 1, <16 x i1> %{{.*}}, <16 x i16> %{{.*}})
@@ -2489,6 +2501,12 @@ __m256i test_mm256_maskz_loadu_epi16(__mmask16 __U, void const *__P) {
return _mm256_maskz_loadu_epi16(__U, __P);
}
+__m128i test_mm_loadu_epi8(void const *__P) {
+ // CHECK-LABEL: @test_mm_loadu_epi8
+ // CHECK: load <2 x i64>, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_loadu_epi8(__P);
+}
+
__m128i test_mm_mask_loadu_epi8(__m128i __W, __mmask16 __U, void const *__P) {
// CHECK-LABEL: @test_mm_mask_loadu_epi8
// CHECK: @llvm.masked.load.v16i8.p0v16i8(<16 x i8>* %{{.*}}, i32 1, <16 x i1> %{{.*}}, <16 x i8> %{{.*}})
@@ -2501,6 +2519,12 @@ __m128i test_mm_maskz_loadu_epi8(__mmask16 __U, void const *__P) {
return _mm_maskz_loadu_epi8(__U, __P);
}
+__m256i test_mm256_loadu_epi8(void const *__P) {
+ // CHECK-LABEL: @test_mm256_loadu_epi8
+ // CHECK: load <4 x i64>, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_loadu_epi8(__P);
+}
+
__m256i test_mm256_mask_loadu_epi8(__m256i __W, __mmask32 __U, void const *__P) {
// CHECK-LABEL: @test_mm256_mask_loadu_epi8
// CHECK: @llvm.masked.load.v32i8.p0v32i8(<32 x i8>* %{{.*}}, i32 1, <32 x i1> %{{.*}}, <32 x i8> %{{.*}})
@@ -2513,24 +2537,48 @@ __m256i test_mm256_maskz_loadu_epi8(__mmask32 __U, void const *__P) {
return _mm256_maskz_loadu_epi8(__U, __P);
}
+void test_mm_storeu_epi16(void *__p, __m128i __a) {
+ // check-label: @test_mm_storeu_epi16
+ // check: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_storeu_epi16(__p, __a);
+}
+
void test_mm_mask_storeu_epi16(void *__P, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_storeu_epi16
// CHECK: @llvm.masked.store.v8i16.p0v8i16(<8 x i16> %{{.*}}, <8 x i16>* %{{.*}}, i32 1, <8 x i1> %{{.*}})
return _mm_mask_storeu_epi16(__P, __U, __A);
}
+void test_mm256_storeu_epi16(void *__P, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_storeu_epi16
+ // CHECK: store <4 x i64> %{{.*}}, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_storeu_epi16(__P, __A);
+}
+
void test_mm256_mask_storeu_epi16(void *__P, __mmask16 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_storeu_epi16
// CHECK: @llvm.masked.store.v16i16.p0v16i16(<16 x i16> %{{.*}}, <16 x i16>* %{{.*}}, i32 1, <16 x i1> %{{.*}})
return _mm256_mask_storeu_epi16(__P, __U, __A);
}
+void test_mm_storeu_epi8(void *__p, __m128i __a) {
+ // check-label: @test_mm_storeu_epi8
+ // check: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, align 1{{$}}
+ return _mm_storeu_epi8(__p, __a);
+}
+
void test_mm_mask_storeu_epi8(void *__P, __mmask16 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_storeu_epi8
// CHECK: @llvm.masked.store.v16i8.p0v16i8(<16 x i8> %{{.*}}, <16 x i8>* %{{.*}}, i32 1, <16 x i1> %{{.*}})
return _mm_mask_storeu_epi8(__P, __U, __A);
}
+void test_mm256_storeu_epi8(void *__P, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_storeu_epi8
+ // CHECK: store <4 x i64> %{{.*}}, <4 x i64>* %{{.*}}, align 1{{$}}
+ return _mm256_storeu_epi8(__P, __A);
+}
+
void test_mm256_mask_storeu_epi8(void *__P, __mmask32 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_storeu_epi8
// CHECK: @llvm.masked.store.v32i8.p0v32i8(<32 x i8> %{{.*}}, <32 x i8>* %{{.*}}, i32 1, <32 x i1> %{{.*}})
diff --git a/test/CodeGen/block-byref-aggr.c b/test/CodeGen/block-byref-aggr.c
index 962f100638..db10576899 100644
--- a/test/CodeGen/block-byref-aggr.c
+++ b/test/CodeGen/block-byref-aggr.c
@@ -9,11 +9,13 @@ Agg makeAgg(void);
// cause a block copy. rdar://9309454
void test0() {
__block Agg a = {100};
+ ^{ (void)a; };
a = makeAgg();
}
// CHECK-LABEL: define void @test0()
// CHECK: [[A:%.*]] = alloca [[BYREF:%.*]], align 8
+// CHECK-NEXT: alloca <{ i8*, i32, i32, i8*, %{{.*}}*, i8* }>, align 8
// CHECK-NEXT: [[TEMP:%.*]] = alloca [[AGG]], align 4
// CHECK: [[RESULT:%.*]] = call i32 @makeAgg()
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[TEMP]], i32 0, i32 0
@@ -35,11 +37,13 @@ void test0() {
// rdar://11757470
void test1() {
__block Agg a, b;
+ ^{ (void)a; (void)b; };
a = b = makeAgg();
}
// CHECK-LABEL: define void @test1()
// CHECK: [[A:%.*]] = alloca [[A_BYREF:%.*]], align 8
// CHECK-NEXT: [[B:%.*]] = alloca [[B_BYREF:%.*]], align 8
+// CHECK-NEXT: alloca <{ i8*, i32, i32, i8*, %{{.*}}*, i8*, i8* }>, align 8
// CHECK-NEXT: [[TEMP:%.*]] = alloca [[AGG]], align 4
// CHECK: [[RESULT:%.*]] = call i32 @makeAgg()
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[TEMP]], i32 0, i32 0
diff --git a/test/CodeGen/blocks-seq.c b/test/CodeGen/blocks-seq.c
index b3e672976c..9b47fbf783 100644
--- a/test/CodeGen/blocks-seq.c
+++ b/test/CodeGen/blocks-seq.c
@@ -11,6 +11,7 @@ int rhs();
void foo() {
__block int i;
+ ^{ (void)i; };
i = rhs();
i += rhs();
}
diff --git a/test/CodeGen/builtin-constant-p.c b/test/CodeGen/builtin-constant-p.c
new file mode 100644
index 0000000000..7f4e7d07cc
--- /dev/null
+++ b/test/CodeGen/builtin-constant-p.c
@@ -0,0 +1,168 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O2 | FileCheck %s
+
+int a = 42;
+
+inline int bcp(int x) {
+ return __builtin_constant_p(x);
+}
+
+/* --- Compound literals */
+
+struct foo { int x, y; };
+
+int y;
+struct foo f = (struct foo){ __builtin_constant_p(y), 42 };
+
+struct foo test0(int expr) {
+ // CHECK: define i64 @test0(i32 %expr)
+ // CHECK: call i1 @llvm.is.constant.i32(i32 %expr)
+ struct foo f = (struct foo){ __builtin_constant_p(expr), 42 };
+ return f;
+}
+
+/* --- Pointer types */
+
+inline int test1_i(int *x) {
+ return *x;
+}
+
+int test1() {
+ // CHECK: define i32 @test1
+ // CHECK: add nsw i32 %0, -13
+ // CHECK-NEXT: call i1 @llvm.is.constant.i32(i32 %sub)
+ return bcp(test1_i(&a) - 13);
+}
+
+int test2() {
+ // CHECK: define i32 @test2
+ // CHECK: ret i32 0
+ return __builtin_constant_p(&a - 13);
+}
+
+inline int test3_i(int *x) {
+ return 42;
+}
+
+int test3() {
+ // CHECK: define i32 @test3
+ // CHECK: ret i32 1
+ return bcp(test3_i(&a) - 13);
+}
+
+/* --- Aggregate types */
+
+int b[] = {1, 2, 3};
+
+int test4() {
+ // CHECK: define i32 @test4
+ // CHECK: ret i32 0
+ return __builtin_constant_p(b);
+}
+
+const char test5_c[] = {1, 2, 3, 0};
+
+int test5() {
+ // CHECK: define i32 @test5
+ // CHECK: ret i32 0
+ return __builtin_constant_p(test5_c);
+}
+
+inline char test6_i(const char *x) {
+ return x[1];
+}
+
+int test6() {
+ // CHECK: define i32 @test6
+ // CHECK: ret i32 0
+ return __builtin_constant_p(test6_i(test5_c));
+}
+
+/* --- Non-constant global variables */
+
+int test7() {
+ // CHECK: define i32 @test7
+ // CHECK: call i1 @llvm.is.constant.i32(i32 %0)
+ return bcp(a);
+}
+
+/* --- Constant global variables */
+
+const int c = 42;
+
+int test8() {
+ // CHECK: define i32 @test8
+ // CHECK: ret i32 1
+ return bcp(c);
+}
+
+/* --- Array types */
+
+int arr[] = { 1, 2, 3 };
+const int c_arr[] = { 1, 2, 3 };
+
+int test9() {
+ // CHECK: define i32 @test9
+ // CHECK: call i1 @llvm.is.constant.i32(i32 %0)
+ return __builtin_constant_p(arr[2]);
+}
+
+int test10() {
+ // CHECK: define i32 @test10
+ // CHECK: ret i32 1
+ return __builtin_constant_p(c_arr[2]);
+}
+
+int test11() {
+ // CHECK: define i32 @test11
+ // CHECK: ret i32 0
+ return __builtin_constant_p(c_arr);
+}
+
+/* --- Function pointers */
+
+int test12() {
+ // CHECK: define i32 @test12
+ // CHECK: ret i32 0
+ return __builtin_constant_p(&test10);
+}
+
+int test13() {
+ // CHECK: define i32 @test13
+ // CHECK: ret i32 1
+ return __builtin_constant_p(&test10 != 0);
+}
+
+typedef unsigned long uintptr_t;
+#define assign(p, v) ({ \
+ uintptr_t _r_a_p__v = (uintptr_t)(v); \
+ if (__builtin_constant_p(v) && _r_a_p__v == (uintptr_t)0) { \
+ union { \
+ uintptr_t __val; \
+ char __c[1]; \
+ } __u = { \
+ .__val = (uintptr_t)_r_a_p__v \
+ }; \
+ *(volatile unsigned int*)&p = *(unsigned int*)(__u.__c); \
+ __u.__val; \
+ } \
+ _r_a_p__v; \
+})
+
+typedef void fn_p(void);
+extern fn_p *dest_p;
+
+static void src_fn(void) {
+}
+
+void test14() {
+ assign(dest_p, src_fn);
+}
+
+extern int test15_v;
+
+struct { const char *t; int a; } test15[] = {
+ { "tag", __builtin_constant_p(test15_v) && !test15_v ? 1 : 0 }
+};
+
+extern char test16_v;
+struct { int a; } test16 = { __builtin_constant_p(test16_v) };
diff --git a/test/CodeGen/builtin-cpu-supports.c b/test/CodeGen/builtin-cpu-supports.c
index b70f4aca9d..d384efbc20 100644
--- a/test/CodeGen/builtin-cpu-supports.c
+++ b/test/CodeGen/builtin-cpu-supports.c
@@ -14,7 +14,14 @@ int main() {
// CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
// CHECK: [[AND:%[^ ]+]] = and i32 [[LOAD]], 256
- // CHECK: = icmp ne i32 [[AND]], 0
+ // CHECK: = icmp eq i32 [[AND]], 256
+
+ if (__builtin_cpu_supports("gfni"))
+ a("gfni");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* @__cpu_features2
+ // CHECK: [[AND:%[^ ]+]] = and i32 [[LOAD]], 1
+ // CHECK: = icmp eq i32 [[AND]], 1
return 0;
}
diff --git a/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c
index a48c202049..2700442681 100644
--- a/test/CodeGen/builtin-memfns.c
+++ b/test/CodeGen/builtin-memfns.c
@@ -111,3 +111,10 @@ void test11() {
memcpy(&d, (char *)&e.a, sizeof(e));
}
+// CHECK-LABEL: @test12
+extern char dest_array[];
+extern char src_array[];
+void test12() {
+ // CHECK: call void @llvm.memcpy{{.*}}(
+ memcpy(&dest_array, &dest_array, 2);
+}
diff --git a/test/CodeGen/builtin-unpredictable.c b/test/CodeGen/builtin-unpredictable.c
index 30709b0cac..bdd62e972b 100644
--- a/test/CodeGen/builtin-unpredictable.c
+++ b/test/CodeGen/builtin-unpredictable.c
@@ -1,10 +1,15 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - -x c++ %s -O1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=CHECK_O0
// When optimizing, the builtin should be converted to metadata.
// When not optimizing, there should be no metadata created for the builtin.
// In both cases, the builtin should be removed from the code.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void foo();
void branch(int x) {
// CHECK-LABEL: define void @branch(
@@ -42,5 +47,10 @@ int unpredictable_switch(int x) {
return 0;
}
+#ifdef __cplusplus
+}
+#endif
+
+
// CHECK: [[METADATA]] = !{}
diff --git a/test/CodeGen/builtins-hexagon-v66-128B.c b/test/CodeGen/builtins-hexagon-v66-128B.c
new file mode 100644
index 0000000000..a1c4786cf2
--- /dev/null
+++ b/test/CodeGen/builtins-hexagon-v66-128B.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple hexagon -target-cpu hexagonv66 -target-feature +hvxv66 -target-feature +hvx-length128b -emit-llvm -o - %s | FileCheck %s
+// REQUIRES: hexagon-registered-target
+
+typedef long HEXAGON_VecPred128 __attribute__((__vector_size__(128)))
+ __attribute__((aligned(128)));
+typedef long HEXAGON_Vect1024 __attribute__((__vector_size__(128)))
+ __attribute__((aligned(128)));
+typedef long HEXAGON_Vect2048 __attribute__((__vector_size__(256)))
+ __attribute__((aligned(256)));
+
+// CHECK-LABEL: @test1
+// CHECK: call <32 x i32> @llvm.hexagon.V6.vaddcarrysat.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}}, <1024 x i1> %{{[0-9]+}})
+HEXAGON_Vect1024 test1(void *in, void *out) {
+ HEXAGON_Vect1024 v1, v2;
+ HEXAGON_Vect1024 *p;
+ HEXAGON_VecPred128 q1;
+
+ p = (HEXAGON_Vect1024 *)in;
+ v1 = *p++;
+ v2 = *p++;
+ q1 = *p++;
+
+ return __builtin_HEXAGON_V6_vaddcarrysat_128B(v1, v2, q1);
+}
+
+// CHECK-LABEL: @test26
+// CHECK: call <32 x i32> @llvm.hexagon.V6.vrotr.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}})
+HEXAGON_Vect1024 test26(void *in, void *out) {
+ HEXAGON_Vect1024 v1, v2;
+ HEXAGON_Vect1024 *p;
+
+ p = (HEXAGON_Vect1024 *)in;
+ v1 = *p++;
+ v2 = *p++;
+
+ return __builtin_HEXAGON_V6_vrotr_128B(v1, v2);
+}
+
+// CHECK-LABEL: @test27
+// CHECK: call <32 x i32> @llvm.hexagon.V6.vsatdw.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}})
+HEXAGON_Vect1024 test27(void *in, void *out) {
+ HEXAGON_Vect1024 v1, v2;
+ HEXAGON_Vect1024 *p;
+
+ p = (HEXAGON_Vect1024 *)in;
+ v1 = *p++;
+ v2 = *p++;
+
+ return __builtin_HEXAGON_V6_vsatdw_128B(v1, v2);
+}
+
+// CHECK-LABEL: @test28
+// CHECK: call <64 x i32> @llvm.hexagon.V6.vasr.into.128B(<64 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}})
+HEXAGON_Vect2048 test28(void *in1, void *in2, void *out) {
+ HEXAGON_Vect1024 v1, v2;
+ HEXAGON_Vect1024 *p1;
+ HEXAGON_Vect2048 *p2;
+ HEXAGON_Vect2048 vr;
+
+ p1 = (HEXAGON_Vect1024 *)in1;
+ v1 = *p1++;
+ v2 = *p1++;
+ p2 = (HEXAGON_Vect2048 *)in2;
+ vr = *p2;
+
+ return __builtin_HEXAGON_V6_vasr_into_128B(vr, v1, v2);
+}
diff --git a/test/CodeGen/builtins-hexagon-v66.c b/test/CodeGen/builtins-hexagon-v66.c
new file mode 100644
index 0000000000..1382f18b4f
--- /dev/null
+++ b/test/CodeGen/builtins-hexagon-v66.c
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -triple hexagon -target-cpu hexagonv66 -target-feature +hvxv66 -target-feature +hvx-length64b -emit-llvm -o - %s | FileCheck %s
+// REQUIRES: hexagon-registered-target
+
+// CHECK-LABEL: @test1
+// CHECK: call i32 @llvm.hexagon.M2.mnaci(i32 %0, i32 %1, i32 %2)
+int test1(int rx, int rs, int rt) {
+ return __builtin_HEXAGON_M2_mnaci(rx, rs, rt);
+}
+
+// CHECK-LABEL: @test2
+// CHECK: call double @llvm.hexagon.F2.dfadd(double %0, double %1)
+double test2(double rss, double rtt) {
+ return __builtin_HEXAGON_F2_dfadd(rss, rtt);
+}
+
+// CHECK-LABEL: @test3
+// CHECK: call double @llvm.hexagon.F2.dfsub(double %0, double %1)
+double test3(double rss, double rtt) {
+ return __builtin_HEXAGON_F2_dfsub(rss, rtt);
+}
+
+// CHECK-LABEL: @test4
+// CHECK: call i32 @llvm.hexagon.S2.mask(i32 1, i32 2)
+int test4() {
+ return __builtin_HEXAGON_S2_mask(1, 2);
+}
+
+typedef long HEXAGON_VecPred64 __attribute__((__vector_size__(64)))
+ __attribute__((aligned(64)));
+typedef long HEXAGON_Vect512 __attribute__((__vector_size__(64)))
+ __attribute__((aligned(64)));
+typedef long HEXAGON_Vect1024 __attribute__((__vector_size__(128)))
+ __attribute__((aligned(128)));
+
+// CHECK-LABEL: @test5
+// CHECK: call <16 x i32> @llvm.hexagon.V6.vaddcarrysat(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}}, <512 x i1> %{{[0-9]+}})
+HEXAGON_Vect512 test5(void *in, void *out) {
+ HEXAGON_Vect512 v1, v2;
+ HEXAGON_Vect512 *p;
+ HEXAGON_VecPred64 q1;
+
+ p = (HEXAGON_Vect512 *)in;
+ v1 = *p++;
+ v2 = *p++;
+ q1 = *p++;
+
+ return __builtin_HEXAGON_V6_vaddcarrysat(v1, v2, q1);
+}
+
+// CHECK-LABEL: @test6
+// CHECK: call <16 x i32> @llvm.hexagon.V6.vrotr(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
+HEXAGON_Vect512 test6(void *in, void *out) {
+ HEXAGON_Vect512 v1, v2;
+ HEXAGON_Vect512 *p;
+
+ p = (HEXAGON_Vect512 *)in;
+ v1 = *p++;
+ v2 = *p++;
+
+ return __builtin_HEXAGON_V6_vrotr(v1, v2);
+}
+
+// CHECK-LABEL: @test7
+// CHECK: call <16 x i32> @llvm.hexagon.V6.vsatdw(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
+HEXAGON_Vect512 test7(void *in, void *out) {
+ HEXAGON_Vect512 v1, v2;
+ HEXAGON_Vect512 *p;
+
+ p = (HEXAGON_Vect512 *)in;
+ v1 = *p++;
+ v2 = *p++;
+
+ return __builtin_HEXAGON_V6_vsatdw(v1, v2);
+}
+
+// CHECK-LABEL: @test8
+// CHECK: call <32 x i32> @llvm.hexagon.V6.vasr.into(<32 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
+HEXAGON_Vect1024 test8(void *in1, void *in2, void *out) {
+ HEXAGON_Vect512 v1, v2;
+ HEXAGON_Vect512 *p1;
+ HEXAGON_Vect1024 *p2;
+ HEXAGON_Vect1024 vr;
+
+ p1 = (HEXAGON_Vect512 *)in1;
+ v1 = *p1++;
+ v2 = *p1++;
+ p2 = (HEXAGON_Vect1024 *)in2;
+ vr = *p2;
+
+ return __builtin_HEXAGON_V6_vasr_into(vr, v1, v2);
+}
diff --git a/test/CodeGen/builtins-hexagon.c b/test/CodeGen/builtins-hexagon.c
index b4c0642ef3..9a1b733da5 100644
--- a/test/CodeGen/builtins-hexagon.c
+++ b/test/CodeGen/builtins-hexagon.c
@@ -426,8 +426,6 @@ void test() {
__builtin_HEXAGON_A5_vaddhubs(0, 0);
// CHECK: @llvm.hexagon.A6.vcmpbeq.notany
__builtin_HEXAGON_A6_vcmpbeq_notany(0, 0);
- // CHECK: @llvm.hexagon.A6.vcmpbeq.notany.128B
- __builtin_HEXAGON_A6_vcmpbeq_notany_128B(0, 0);
// CHECK: @llvm.hexagon.C2.all8
__builtin_HEXAGON_C2_all8(0);
// CHECK: @llvm.hexagon.C2.and
@@ -1400,8 +1398,6 @@ void test() {
__builtin_HEXAGON_S2_brev(0);
// CHECK: @llvm.hexagon.S2.brevp
__builtin_HEXAGON_S2_brevp(0);
- // CHECK: @llvm.hexagon.S2.cabacencbin
- __builtin_HEXAGON_S2_cabacencbin(0, 0, 0);
// CHECK: @llvm.hexagon.S2.cl0
__builtin_HEXAGON_S2_cl0(0);
// CHECK: @llvm.hexagon.S2.cl0p
diff --git a/test/CodeGen/builtins-mips-msa-error.c b/test/CodeGen/builtins-mips-msa-error.c
index 11750922bb..0454a19b1c 100644
--- a/test/CodeGen/builtins-mips-msa-error.c
+++ b/test/CodeGen/builtins-mips-msa-error.c
@@ -1,18 +1,22 @@
// REQUIRES: mips-registered-target
-// RUN: not %clang_cc1 -triple mips-unknown-linux-gnu -fsyntax-only %s \
+// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -fsyntax-only %s \
// RUN: -target-feature +msa -target-feature +fp64 \
-// RUN: -mfloat-abi hard -o - 2>&1 | FileCheck %s
+// RUN: -verify -mfloat-abi hard -o - 2>&1
#include <msa.h>
void test(void) {
v16i8 v16i8_a = (v16i8) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+ v16i8 v16i8_b = (v16i8) {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
v16i8 v16i8_r;
v8i16 v8i16_a = (v8i16) {0, 1, 2, 3, 4, 5, 6, 7};
+ v8i16 v8i16_b = (v8i16) {8, 9, 10, 11, 12, 13, 14, 15};
v8i16 v8i16_r;
v4i32 v4i32_a = (v4i32) {0, 1, 2, 3};
+ v4i32 v4i32_b = (v4i32) {4, 5, 6, 7};
v4i32 v4i32_r;
v2i64 v2i64_a = (v2i64) {0, 1};
+ v2i64 v2i64_b = (v2i64) {3, 4};
v2i64 v2i64_r;
v16u8 v16u8_a = (v16u8) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
@@ -24,388 +28,385 @@ void test(void) {
v2u64 v2u64_a = (v2u64) {0, 1};
v2u64 v2u64_r;
-
int int_r;
long long ll_r;
- v16u8_r = __msa_addvi_b(v16u8_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_addvi_h(v8u16_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_addvi_w(v4u32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_addvi_d(v2u64_a, 32); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_andi_b(v16i8_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v8i16_r = __msa_andi_b(v8i16_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v4i32_r = __msa_andi_b(v4i32_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v2i64_r = __msa_andi_b(v2i64_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bclri_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_bclri_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_bclri_w(v4i32_a, 33); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_bclri_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_binsli_b(v16i8_r, v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_binsli_h(v8i16_r, v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_binsli_w(v4i32_r, v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_binsli_d(v2i64_r, v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_binsri_b(v16i8_r, v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_binsri_h(v8i16_r, v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_binsri_w(v4i32_r, v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_binsri_d(v2i64_r, v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_bmnzi_b(v16i8_r, v16i8_a, 256); // expected-error {{argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bmzi_b(v16i8_r, v16i8_a, 256); // expected-error {{argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bnegi_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_bnegi_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_bnegi_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_bnegi_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_bseli_b(v16i8_r, v16i8_a, 256); // expected-error {{argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bseti_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_bseti_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_bseti_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_bseti_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_ceqi_b(v16i8_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_ceqi_h(v8i16_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_ceqi_w(v4i32_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_ceqi_d(v2i64_a, 16); // expected-error {{argument should be a value from -16 to 15}}
-
- v16i8_r = __msa_clei_s_b(v16i8_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_clei_s_h(v8i16_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_clei_s_w(v4i32_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_clei_s_d(v2i64_a, 16); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_clei_u_b(v16u8_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_clei_u_h(v8u16_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_clei_u_w(v4u32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_clei_u_d(v2u64_a, 32); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_clti_s_b(v16i8_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_clti_s_h(v8i16_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_clti_s_w(v4i32_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_clti_s_d(v2i64_a, 16); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_clti_u_b(v16u8_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_clti_u_h(v8u16_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_clti_u_w(v4u32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_clti_u_d(v2u64_a, 32); // expected-error {{argument should be a value from 0 to 31}}
-
- int_r = __msa_copy_s_b(v16i8_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- int_r = __msa_copy_s_h(v8i16_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- int_r = __msa_copy_s_w(v4i32_a, 4); // expected-error {{argument should be a value from 0 to 3}}
- ll_r = __msa_copy_s_d(v2i64_a, 2); // expected-error {{argument should be a value from 0 to 1}}
-
- int_r = __msa_copy_u_b(v16u8_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- int_r = __msa_copy_u_h(v8u16_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- int_r = __msa_copy_u_w(v4u32_a, 4); // expected-error {{argument should be a value from 0 to 3}}
- ll_r = __msa_copy_u_d(v2i64_a, 2); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_insve_b(v16i8_r, 16, v16i8_a); // expected-error {{argument should be a value from 0 to 15}}
- v8i16_r = __msa_insve_h(v8i16_r, 8, v8i16_a); // expected-error {{argument should be a value from 0 to 7}}
- v4i32_r = __msa_insve_w(v4i32_r, 4, v4i32_a); // expected-error {{argument should be a value from 0 to 3}}
- v2i64_r = __msa_insve_d(v2i64_r, 2, v2i64_a); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_ld_b(&v16i8_a, 23); // expected-error {{argument should be a multiple of 16}}
- v8i16_r = __msa_ld_h(&v8i16_a, 77); // expected-error {{argument should be a multiple of 16}}
- v4i32_r = __msa_ld_w(&v4i32_a, 14); // expected-error {{argument should be a multiple of 16}}
- v2i64_r = __msa_ld_d(&v2i64_a, 23); // expected-error {{argument should be a multiple of 16}}
-
- v16i8_r = __msa_ld_b(&v16i8_a, 512); // expected-error {{argument should be a value from -512 to 511}}
- v8i16_r = __msa_ld_h(&v8i16_a, 512); // expected-error {{argument should be a value from -512 to 511}}
- v4i32_r = __msa_ld_w(&v4i32_a, 512); // expected-error {{argument should be a value from -512 to 511}}
- v2i64_r = __msa_ld_d(&v2i64_a, 512); // expected-error {{argument should be a value from -512 to 511}}
-
- v16i8_r = __msa_ldi_b(256); // expected-error {{argument should be a value from -128 to 255}}
- v8i16_r = __msa_ldi_h(512); // expected-error {{argument should be a value from -512 to 511}}
- v4i32_r = __msa_ldi_w(512); // expected-error {{argument should be a value from -512 to 511}}
- v2i64_r = __msa_ldi_d(512); // expected-error {{argument should be a value from -512 to 511}}
-
- v16i8_r = __msa_maxi_s_b(v16i8_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_maxi_s_h(v8i16_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_maxi_s_w(v4i32_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_maxi_s_d(v2i64_a, 16); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_maxi_u_b(v16u8_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_maxi_u_h(v8u16_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_maxi_u_w(v4u32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_maxi_u_d(v2u64_a, 32); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_mini_s_b(v16i8_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_mini_s_h(v8i16_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_mini_s_w(v4i32_a, 16); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_mini_s_d(v2i64_a, 16); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_mini_u_b(v16u8_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_mini_u_h(v8u16_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_mini_u_w(v4u32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_mini_u_d(v2u64_a, 32); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_nori_b(v16i8_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_ori_b(v16i8_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_sat_s_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_sat_s_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_sat_s_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_sat_s_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_sat_u_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_sat_u_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_sat_u_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_sat_u_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_shf_b(v16i8_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v8i16_r = __msa_shf_h(v8i16_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v4i32_r = __msa_shf_w(v4i32_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, 4); // expected-error {{argument should be a value from 0 to 3}}
- v2i64_r = __msa_sldi_d(v2i64_r, v2i64_a, 2); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_slli_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_slli_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_slli_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_slli_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_splati_b(v16i8_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v8i16_r = __msa_splati_h(v8i16_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v4i32_r = __msa_splati_w(v4i32_a, 4); // expected-error {{argument should be a value from 0 to 3}}
- v2i64_r = __msa_splati_d(v2i64_a, 2); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_srai_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srai_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srai_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srai_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_srari_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srari_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srari_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srari_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_srli_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srli_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srli_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srli_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_srlri_b(v16i8_a, 8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srlri_h(v8i16_a, 16); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srlri_w(v4i32_a, 32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srlri_d(v2i64_a, 64); // expected-error {{argument should be a value from 0 to 63}}
-
- __msa_st_b(v16i8_b, &v16i8_a, 52); // expected-error {{argument should be a multiple of 16}}
- __msa_st_h(v8i16_b, &v8i16_a, 51); // expected-error {{argument should be a multiple of 16}}
- __msa_st_w(v4i32_b, &v4i32_a, 51); // expected-error {{argument should be a multiple of 16}}
- __msa_st_d(v2i64_b, &v2i64_a, 12); // expected-error {{argument should be a multiple of 16}}
-
- __msa_st_b(v16i8_b, &v16i8_a, 512); // expected-error {{argument should be a value from -512 to 511}}
- __msa_st_h(v8i16_b, &v8i16_a, 512); // expected-error {{argument should be a value from -512 to 511}}
- __msa_st_w(v4i32_b, &v4i32_a, 512); // expected-error {{argument should be a value from -512 to 511}}
- __msa_st_d(v2i64_b, &v2i64_a, 512); // expected-error {{argument should be a value from -512 to 511}}
-
- v16i8_r = __msa_subvi_b(v16i8_a, 256); // expected-error {{argument should be a value from 0 to 31}}
- v8i16_r = __msa_subvi_h(v8i16_a, 256); // expected-error {{argument should be a value from 0 to 31}}
- v4i32_r = __msa_subvi_w(v4i32_a, 256); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_subvi_d(v2i64_a, 256); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_xori_b(v16i8_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v8i16_r = __msa_xori_b(v8i16_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v4i32_r = __msa_xori_b(v4i32_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v2i64_r = __msa_xori_b(v2i64_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16u8_r = __msa_xori_b(v16u8_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v8u16_r = __msa_xori_b(v8u16_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v4u32_r = __msa_xori_b(v4u32_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
- v2u64_r = __msa_xori_b(v2u64_a, 256); // CHECK: warning: argument should be a value from 0 to 255}}
+ v16u8_r = __msa_addvi_b(v16u8_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_addvi_h(v8u16_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_addvi_w(v4u32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_addvi_d(v2u64_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_andi_b(v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v8i16_r = __msa_andi_b(v8i16_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v4i32_r = __msa_andi_b(v4i32_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v2i64_r = __msa_andi_b(v2i64_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bclri_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_bclri_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_bclri_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_bclri_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_binsli_b(v16i8_r, v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_binsli_h(v8i16_r, v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_binsli_w(v4i32_r, v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_binsli_d(v2i64_r, v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_binsri_b(v16i8_r, v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_binsri_h(v8i16_r, v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_binsri_w(v4i32_r, v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_binsri_d(v2i64_r, v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_bmnzi_b(v16i8_r, v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bmzi_b(v16i8_r, v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bnegi_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_bnegi_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_bnegi_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_bnegi_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_bseli_b(v16i8_r, v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bseti_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_bseti_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_bseti_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_bseti_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_ceqi_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_ceqi_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_ceqi_w(v4i32_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_ceqi_d(v2i64_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+
+ v16i8_r = __msa_clei_s_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_clei_s_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_clei_s_w(v4i32_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_clei_s_d(v2i64_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_clei_u_b(v16u8_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_clei_u_h(v8u16_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_clei_u_w(v4u32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_clei_u_d(v2u64_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_clti_s_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_clti_s_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_clti_s_w(v4i32_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_clti_s_d(v2i64_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_clti_u_b(v16u8_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_clti_u_h(v8u16_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_clti_u_w(v4u32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_clti_u_d(v2u64_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+
+ int_r = __msa_copy_s_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ int_r = __msa_copy_s_h(v8i16_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ int_r = __msa_copy_s_w(v4i32_a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ ll_r = __msa_copy_s_d(v2i64_a, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+ int_r = __msa_copy_u_b(v16u8_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ int_r = __msa_copy_u_h(v8u16_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ int_r = __msa_copy_u_w(v4u32_a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ ll_r = __msa_copy_u_d(v2i64_a, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_insve_b(v16i8_r, 16, v16i8_a); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v8i16_r = __msa_insve_h(v8i16_r, 8, v8i16_a); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v4i32_r = __msa_insve_w(v4i32_r, 4, v4i32_a); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ v2i64_r = __msa_insve_d(v2i64_r, 2, v2i64_a); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+ v8i16_r = __msa_ld_h(&v8i16_a, 77); // expected-error {{argument should be a multiple of 2}}
+ v4i32_r = __msa_ld_w(&v4i32_a, 14); // expected-error {{argument should be a multiple of 4}}
+ v2i64_r = __msa_ld_d(&v2i64_a, 23); // expected-error {{argument should be a multiple of 8}}
+
+ v16i8_r = __msa_ld_b(&v16i8_a, 512); // expected-error {{argument value 512 is outside the valid range [-512, 511]}}
+ v8i16_r = __msa_ld_h(&v8i16_a, 1024); // expected-error {{argument value 1024 is outside the valid range [-1024, 1022]}}
+ v4i32_r = __msa_ld_w(&v4i32_a, 2048); // expected-error {{argument value 2048 is outside the valid range [-2048, 2044]}}
+ v2i64_r = __msa_ld_d(&v2i64_a, 4096); // expected-error {{argument value 4096 is outside the valid range [-4096, 4088]}}
+
+ v16i8_r = __msa_ldi_b(256); // expected-error {{argument value 256 is outside the valid range [-128, 255]}}
+ v8i16_r = __msa_ldi_h(512); // expected-error {{argument value 512 is outside the valid range [-512, 511]}}
+ v4i32_r = __msa_ldi_w(512); // expected-error {{argument value 512 is outside the valid range [-512, 511]}}
+ v2i64_r = __msa_ldi_d(512); // expected-error {{argument value 512 is outside the valid range [-512, 511]}}
+
+ v16i8_r = __msa_maxi_s_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_maxi_s_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_maxi_s_w(v4i32_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_maxi_s_d(v2i64_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_maxi_u_b(v16u8_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_maxi_u_h(v8u16_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_maxi_u_w(v4u32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_maxi_u_d(v2u64_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_mini_s_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_mini_s_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_mini_s_w(v4i32_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_mini_s_d(v2i64_a, 16); // expected-error {{argument value 16 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_mini_u_b(v16u8_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_mini_u_h(v8u16_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_mini_u_w(v4u32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_mini_u_d(v2u64_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_nori_b(v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_ori_b(v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_sat_s_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_sat_s_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_sat_s_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_sat_s_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_sat_u_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_sat_u_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_sat_u_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_sat_u_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_shf_b(v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v8i16_r = __msa_shf_h(v8i16_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v4i32_r = __msa_shf_w(v4i32_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ v2i64_r = __msa_sldi_d(v2i64_r, v2i64_a, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_slli_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_slli_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_slli_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_slli_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_splati_b(v16i8_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v8i16_r = __msa_splati_h(v8i16_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v4i32_r = __msa_splati_w(v4i32_a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ v2i64_r = __msa_splati_d(v2i64_a, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_srai_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srai_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srai_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srai_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_srari_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srari_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srari_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srari_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_srli_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srli_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srli_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srli_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_srlri_b(v16i8_a, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srlri_h(v8i16_a, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srlri_w(v4i32_a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srlri_d(v2i64_a, 64); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
+
+ __msa_st_h(v8i16_b, &v8i16_a, 51); // expected-error {{argument should be a multiple of 2}}
+ __msa_st_w(v4i32_b, &v4i32_a, 51); // expected-error {{argument should be a multiple of 4}}
+ __msa_st_d(v2i64_b, &v2i64_a, 12); // expected-error {{argument should be a multiple of 8}}
+
+ __msa_st_b(v16i8_b, &v16i8_a, 512); // expected-error {{argument value 512 is outside the valid range [-512, 511]}}
+ __msa_st_h(v8i16_b, &v8i16_a, 1024); // expected-error {{argument value 1024 is outside the valid range [-1024, 1022]}}
+ __msa_st_w(v4i32_b, &v4i32_a, 2048); // expected-error {{argument value 2048 is outside the valid range [-2048, 2044]}}
+ __msa_st_d(v2i64_b, &v2i64_a, 4096); // expected-error {{argument value 4096 is outside the valid range [-4096, 4088]}}
+
+ v16i8_r = __msa_subvi_b(v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 31]}}
+ v8i16_r = __msa_subvi_h(v8i16_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 31]}}
+ v4i32_r = __msa_subvi_w(v4i32_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_subvi_d(v2i64_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_xori_b(v16i8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v8i16_r = __msa_xori_b(v8i16_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v4i32_r = __msa_xori_b(v4i32_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v2i64_r = __msa_xori_b(v2i64_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+
+ v16u8_r = __msa_xori_b(v16u8_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v8u16_r = __msa_xori_b(v8u16_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v4u32_r = __msa_xori_b(v4u32_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
+ v2u64_r = __msa_xori_b(v2u64_a, 256); // expected-error {{argument value 256 is outside the valid range [0, 255]}}
// Test the lower bounds
- v16u8_r = __msa_addvi_b(v16u8_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_addvi_h(v8u16_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_addvi_w(v4u32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_addvi_d(v2u64_a, -1); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_andi_b(v16i8_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v8i16_r = __msa_andi_b(v8i16_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v4i32_r = __msa_andi_b(v4i32_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v2i64_r = __msa_andi_b(v2i64_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bclri_b(v16i8_a, -1); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_bclri_h(v8i16_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_bclri_w(v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_bclri_d(v2i64_a, -1); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_binsli_b(v16i8_r, v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_binsli_h(v8i16_r, v8i16_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_binsli_w(v4i32_r, v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_binsli_d(v2i64_r, v2i64_a, -1); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_binsri_b(v16i8_r, v16i8_a, -1); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_binsri_h(v8i16_r, v8i16_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_binsri_w(v4i32_r, v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_binsri_d(v2i64_r, v2i64_a, -1); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_bmnzi_b(v16i8_r, v16i8_a, -1); // expected-error {{argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bmzi_b(v16i8_r, v16i8_a, -1); // expected-error {{argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bnegi_b(v16i8_a, -1); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_bnegi_h(v8i16_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_bnegi_w(v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_bnegi_d(v2i64_a, -1); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_bseli_b(v16i8_r, v16i8_a, -1); // expected-error {{argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_bseti_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_bseti_h(v8i16_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_bseti_w(v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_bseti_d(v2i64_a, -1); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_ceqi_b(v16i8_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_ceqi_h(v8i16_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_ceqi_w(v4i32_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_ceqi_d(v2i64_a, -17); // expected-error {{argument should be a value from -16 to 15}}
-
- v16i8_r = __msa_clei_s_b(v16i8_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_clei_s_h(v8i16_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_clei_s_w(v4i32_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_clei_s_d(v2i64_a, -17); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_clei_u_b(v16u8_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_clei_u_h(v8u16_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_clei_u_w(v4u32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_clei_u_d(v2u64_a, -1); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_clti_s_b(v16i8_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_clti_s_h(v8i16_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_clti_s_w(v4i32_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_clti_s_d(v2i64_a, -17); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_clti_u_b(v16u8_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_clti_u_h(v8u16_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_clti_u_w(v4u32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_clti_u_d(v2u64_a, -1); // expected-error {{argument should be a value from 0 to 31}}
-
- int_r = __msa_copy_s_b(v16i8_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- int_r = __msa_copy_s_h(v8i16_a, -1); // expected-error {{argument should be a value from 0 to 7}}
- int_r = __msa_copy_s_w(v4i32_a, -1); // expected-error {{argument should be a value from 0 to 3}}
- ll_r = __msa_copy_s_d(v2i64_a, -1); // expected-error {{argument should be a value from 0 to 1}}
-
- int_r = __msa_copy_u_b(v16u8_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- int_r = __msa_copy_u_h(v8u16_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- int_r = __msa_copy_u_w(v4u32_a, -4); // expected-error {{argument should be a value from 0 to 3}}
- ll_r = __msa_copy_u_d(v2i64_a, -2); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_insve_b(v16i8_r, 16, v16i8_a); // expected-error {{argument should be a value from 0 to 15}}
- v8i16_r = __msa_insve_h(v8i16_r, 8, v8i16_a); // expected-error {{argument should be a value from 0 to 7}}
- v4i32_r = __msa_insve_w(v4i32_r, 4, v4i32_a); // expected-error {{argument should be a value from 0 to 3}}
- v2i64_r = __msa_insve_d(v2i64_r, 2, v2i64_a); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_ld_b(&v16i8_a, -513); // expected-error {{argument should be a value from -512 to 511}}
- v8i16_r = __msa_ld_h(&v8i16_a, -513); // expected-error {{argument should be a value from -512 to 511}}
- v4i32_r = __msa_ld_w(&v4i32_a, -513); // expected-error {{argument should be a value from -512 to 511}}
- v2i64_r = __msa_ld_d(&v2i64_a, -513); // expected-error {{argument should be a value from -512 to 511}}
-
- v16i8_r = __msa_ldi_b(-129); // expected-error {{argument should be a value from -128 to 255}}
- v8i16_r = __msa_ldi_h(-513); // expected-error {{argument should be a value from -512 to 511}}
- v4i32_r = __msa_ldi_w(-513); // expected-error {{argument should be a value from -512 to 511}}
- v2i64_r = __msa_ldi_d(-513); // expected-error {{argument should be a value from -512 to 511}}
-
- v16i8_r = __msa_maxi_s_b(v16i8_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_maxi_s_h(v8i16_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_maxi_s_w(v4i32_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_maxi_s_d(v2i64_a, -17); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_maxi_u_b(v16u8_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_maxi_u_h(v8u16_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_maxi_u_w(v4u32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_maxi_u_d(v2u64_a, -1); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_mini_s_b(v16i8_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v8i16_r = __msa_mini_s_h(v8i16_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v4i32_r = __msa_mini_s_w(v4i32_a, -17); // expected-error {{argument should be a value from -16 to 15}}
- v2i64_r = __msa_mini_s_d(v2i64_a, -17); // expected-error {{argument should be a value from -16 to 15}}
-
- v16u8_r = __msa_mini_u_b(v16u8_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v8u16_r = __msa_mini_u_h(v8u16_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v4u32_r = __msa_mini_u_w(v4u32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2u64_r = __msa_mini_u_d(v2u64_a, -1); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_nori_b(v16i8_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_ori_b(v16i8_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_sat_s_b(v16i8_a, -1); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_sat_s_h(v8i16_a, -1); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_sat_s_w(v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_sat_s_d(v2i64_a, -1); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_sat_u_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_sat_u_h(v8i16_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_sat_u_w(v4i32_a, -32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_sat_u_d(v2i64_a, -64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_shf_b(v16i8_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v8i16_r = __msa_shf_h(v8i16_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v4i32_r = __msa_shf_w(v4i32_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, -4); // expected-error {{argument should be a value from 0 to 3}}
- v2i64_r = __msa_sldi_d(v2i64_r, v2i64_a, -2); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_slli_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_slli_h(v8i16_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_slli_w(v4i32_a, -32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_slli_d(v2i64_a, -64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_splati_b(v16i8_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v8i16_r = __msa_splati_h(v8i16_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v4i32_r = __msa_splati_w(v4i32_a, -4); // expected-error {{argument should be a value from 0 to 3}}
- v2i64_r = __msa_splati_d(v2i64_a, -2); // expected-error {{argument should be a value from 0 to 1}}
-
- v16i8_r = __msa_srai_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srai_h(v8i16_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srai_w(v4i32_a, -32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srai_d(v2i64_a, -64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_srari_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srari_h(v8i16_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srari_w(v4i32_a, -32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srari_d(v2i64_a, -64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_srli_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srli_h(v8i16_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srli_w(v4i32_a, -32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srli_d(v2i64_a, -64); // expected-error {{argument should be a value from 0 to 63}}
-
- v16i8_r = __msa_srlri_b(v16i8_a, -8); // expected-error {{argument should be a value from 0 to 7}}
- v8i16_r = __msa_srlri_h(v8i16_a, -17); // expected-error {{argument should be a value from 0 to 15}}
- v4i32_r = __msa_srlri_w(v4i32_a, -32); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_srlri_d(v2i64_a, -64); // expected-error {{argument should be a value from 0 to 63}}
-
- __msa_st_b(v16i8_b, &v16i8_a, -513); // expected-error {{argument should be a value from -512 to 511}}
- __msa_st_h(v8i16_b, &v8i16_a, -513); // expected-error {{argument should be a value from -512 to 511}}
- __msa_st_w(v4i32_b, &v4i32_a, -513); // expected-error {{argument should be a value from -512 to 511}}
- __msa_st_d(v2i64_b, &v2i64_a, -513); // expected-error {{argument should be a value from -512 to 511}}
-
- v16i8_r = __msa_subvi_b(v16i8_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v8i16_r = __msa_subvi_h(v8i16_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v4i32_r = __msa_subvi_w(v4i32_a, -1); // expected-error {{argument should be a value from 0 to 31}}
- v2i64_r = __msa_subvi_d(v2i64_a, -1); // expected-error {{argument should be a value from 0 to 31}}
-
- v16i8_r = __msa_xori_b(v16i8_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v8i16_r = __msa_xori_b(v8i16_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v4i32_r = __msa_xori_b(v4i32_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v2i64_r = __msa_xori_b(v2i64_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
-
- v16u8_r = __msa_xori_b(v16u8_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v8u16_r = __msa_xori_b(v8u16_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v4u32_r = __msa_xori_b(v4u32_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
- v2u64_r = __msa_xori_b(v2u64_a, -1); // CHECK: warning: argument should be a value from 0 to 255}}
+ v16u8_r = __msa_addvi_b(v16u8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_addvi_h(v8u16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_addvi_w(v4u32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_addvi_d(v2u64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_andi_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v8i16_r = __msa_andi_b(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v4i32_r = __msa_andi_b(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v2i64_r = __msa_andi_b(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bclri_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_bclri_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_bclri_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_bclri_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_binsli_b(v16i8_r, v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_binsli_h(v8i16_r, v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_binsli_w(v4i32_r, v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_binsli_d(v2i64_r, v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_binsri_b(v16i8_r, v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_binsri_h(v8i16_r, v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_binsri_w(v4i32_r, v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_binsri_d(v2i64_r, v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_bmnzi_b(v16i8_r, v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bmzi_b(v16i8_r, v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bnegi_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_bnegi_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_bnegi_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_bnegi_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_bseli_b(v16i8_r, v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_bseti_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_bseti_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_bseti_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_bseti_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_ceqi_b(v16i8_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_ceqi_h(v8i16_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_ceqi_w(v4i32_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_ceqi_d(v2i64_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+
+ v16i8_r = __msa_clei_s_b(v16i8_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_clei_s_h(v8i16_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_clei_s_w(v4i32_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_clei_s_d(v2i64_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_clei_u_b(v16u8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_clei_u_h(v8u16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_clei_u_w(v4u32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_clei_u_d(v2u64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_clti_s_b(v16i8_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_clti_s_h(v8i16_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_clti_s_w(v4i32_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_clti_s_d(v2i64_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_clti_u_b(v16u8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_clti_u_h(v8u16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_clti_u_w(v4u32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_clti_u_d(v2u64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+
+ int_r = __msa_copy_s_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ int_r = __msa_copy_s_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ int_r = __msa_copy_s_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 3]}}
+ ll_r = __msa_copy_s_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 1]}}
+
+ int_r = __msa_copy_u_b(v16u8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ int_r = __msa_copy_u_h(v8u16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ int_r = __msa_copy_u_w(v4u32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 3]}}
+ ll_r = __msa_copy_u_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_insve_b(v16i8_r, 16, v16i8_a); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+ v8i16_r = __msa_insve_h(v8i16_r, 8, v8i16_a); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+ v4i32_r = __msa_insve_w(v4i32_r, 4, v4i32_a); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ v2i64_r = __msa_insve_d(v2i64_r, 2, v2i64_a); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_ld_b(&v16i8_a, -513); // expected-error {{argument value -513 is outside the valid range [-512, 511]}}
+ v8i16_r = __msa_ld_h(&v8i16_a, -1028); // expected-error {{argument value -1028 is outside the valid range [-1024, 1022]}}
+ v4i32_r = __msa_ld_w(&v4i32_a, -2052); // expected-error {{argument value -2052 is outside the valid range [-2048, 2044]}}
+ v2i64_r = __msa_ld_d(&v2i64_a, -4104); // expected-error {{argument value -4104 is outside the valid range [-4096, 4088]}}
+
+ v16i8_r = __msa_ldi_b(-129); // expected-error {{argument value -129 is outside the valid range [-128, 255]}}
+ v8i16_r = __msa_ldi_h(-513); // expected-error {{argument value -513 is outside the valid range [-512, 511]}}
+ v4i32_r = __msa_ldi_w(-513); // expected-error {{argument value -513 is outside the valid range [-512, 511]}}
+ v2i64_r = __msa_ldi_d(-513); // expected-error {{argument value -513 is outside the valid range [-512, 511]}}
+
+ v16i8_r = __msa_maxi_s_b(v16i8_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_maxi_s_h(v8i16_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_maxi_s_w(v4i32_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_maxi_s_d(v2i64_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_maxi_u_b(v16u8_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_maxi_u_h(v8u16_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_maxi_u_w(v4u32_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_maxi_u_d(v2u64_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_mini_s_b(v16i8_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v8i16_r = __msa_mini_s_h(v8i16_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v4i32_r = __msa_mini_s_w(v4i32_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+ v2i64_r = __msa_mini_s_d(v2i64_a, -17); // expected-error {{argument value -17 is outside the valid range [-16, 15]}}
+
+ v16u8_r = __msa_mini_u_b(v16u8_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+ v8u16_r = __msa_mini_u_h(v8u16_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+ v4u32_r = __msa_mini_u_w(v4u32_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+ v2u64_r = __msa_mini_u_d(v2u64_a, -1); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_nori_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_ori_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_sat_s_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_sat_s_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_sat_s_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_sat_s_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_sat_u_b(v16i8_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_sat_u_h(v8i16_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_sat_u_w(v4i32_a, -32); // expected-error {{argument value 4294967264 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_sat_u_d(v2i64_a, -64); // expected-error {{argument value 4294967232 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_shf_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v8i16_r = __msa_shf_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v4i32_r = __msa_shf_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, -4); // expected-error {{argument value 4294967292 is outside the valid range [0, 3]}}
+ v2i64_r = __msa_sldi_d(v2i64_r, v2i64_a, -2); // expected-error {{argument value 4294967294 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_slli_b(v16i8_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_slli_h(v8i16_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_slli_w(v4i32_a, -32); // expected-error {{argument value 4294967264 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_slli_d(v2i64_a, -64); // expected-error {{argument value 4294967232 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_splati_b(v16i8_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v8i16_r = __msa_splati_h(v8i16_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v4i32_r = __msa_splati_w(v4i32_a, -4); // expected-error {{argument value 4294967292 is outside the valid range [0, 3]}}
+ v2i64_r = __msa_splati_d(v2i64_a, -2); // expected-error {{argument value 4294967294 is outside the valid range [0, 1]}}
+
+ v16i8_r = __msa_srai_b(v16i8_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srai_h(v8i16_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srai_w(v4i32_a, -32); // expected-error {{argument value 4294967264 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srai_d(v2i64_a, -64); // expected-error {{argument value 4294967232 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_srari_b(v16i8_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srari_h(v8i16_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srari_w(v4i32_a, -32); // expected-error {{argument value 4294967264 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srari_d(v2i64_a, -64); // expected-error {{argument value 4294967232 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_srli_b(v16i8_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srli_h(v8i16_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srli_w(v4i32_a, -32); // expected-error {{argument value 4294967264 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srli_d(v2i64_a, -64); // expected-error {{argument value 4294967232 is outside the valid range [0, 63]}}
+
+ v16i8_r = __msa_srlri_b(v16i8_a, -8); // expected-error {{argument value 4294967288 is outside the valid range [0, 7]}}
+ v8i16_r = __msa_srlri_h(v8i16_a, -17); // expected-error {{argument value 4294967279 is outside the valid range [0, 15]}}
+ v4i32_r = __msa_srlri_w(v4i32_a, -32); // expected-error {{argument value 4294967264 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_srlri_d(v2i64_a, -64); // expected-error {{argument value 4294967232 is outside the valid range [0, 63]}}
+
+ __msa_st_b(v16i8_b, &v16i8_a, -513); // expected-error {{argument value -513 is outside the valid range [-512, 511]}}
+ __msa_st_h(v8i16_b, &v8i16_a, -1025); // expected-error {{argument value -1025 is outside the valid range [-1024, 1022]}}
+ __msa_st_w(v4i32_b, &v4i32_a, -2049); // expected-error {{argument value -2049 is outside the valid range [-2048, 2044]}}
+ __msa_st_d(v2i64_b, &v2i64_a, -4097); // expected-error {{argument value -4097 is outside the valid range [-4096, 4088]}}
+
+ v16i8_r = __msa_subvi_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v8i16_r = __msa_subvi_h(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v4i32_r = __msa_subvi_w(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+ v2i64_r = __msa_subvi_d(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 31]}}
+
+ v16i8_r = __msa_xori_b(v16i8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v8i16_r = __msa_xori_b(v8i16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v4i32_r = __msa_xori_b(v4i32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v2i64_r = __msa_xori_b(v2i64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+
+ v16u8_r = __msa_xori_b(v16u8_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v8u16_r = __msa_xori_b(v8u16_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v4u32_r = __msa_xori_b(v4u32_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
+ v2u64_r = __msa_xori_b(v2u64_a, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 255]}}
}
diff --git a/test/CodeGen/builtins-mips-msa.c b/test/CodeGen/builtins-mips-msa.c
index 9d09a42090..69c48a1075 100644
--- a/test/CodeGen/builtins-mips-msa.c
+++ b/test/CodeGen/builtins-mips-msa.c
@@ -520,10 +520,10 @@ void test(void) {
v4i32_r = __msa_insve_w(v4i32_r, 1, v4i32_a); // CHECK: call <4 x i32> @llvm.mips.insve.w(
v2i64_r = __msa_insve_d(v2i64_r, 1, v2i64_a); // CHECK: call <2 x i64> @llvm.mips.insve.d(
- v16i8_r = __msa_ld_b(&v16i8_a, 16); // CHECK: call <16 x i8> @llvm.mips.ld.b(
- v8i16_r = __msa_ld_h(&v8i16_a, 32); // CHECK: call <8 x i16> @llvm.mips.ld.h(
- v4i32_r = __msa_ld_w(&v4i32_a, 48); // CHECK: call <4 x i32> @llvm.mips.ld.w(
- v2i64_r = __msa_ld_d(&v2i64_a, 96); // CHECK: call <2 x i64> @llvm.mips.ld.d(
+ v16i8_r = __msa_ld_b(&v16i8_a, 1); // CHECK: call <16 x i8> @llvm.mips.ld.b(
+ v8i16_r = __msa_ld_h(&v8i16_a, 2); // CHECK: call <8 x i16> @llvm.mips.ld.h(
+ v4i32_r = __msa_ld_w(&v4i32_a, 4); // CHECK: call <4 x i32> @llvm.mips.ld.w(
+ v2i64_r = __msa_ld_d(&v2i64_a, 8); // CHECK: call <2 x i64> @llvm.mips.ld.d(
v16i8_r = __msa_ldi_b(3); // CHECK: call <16 x i8> @llvm.mips.ldi.b(
v16i8_r = __msa_ldi_b(-128); // CHECK: call <16 x i8> @llvm.mips.ldi.b(
@@ -771,10 +771,10 @@ void test(void) {
v4i32_r = __msa_srlri_w(v4i32_a, 3); // CHECK: call <4 x i32> @llvm.mips.srlri.w(
v2i64_r = __msa_srlri_d(v2i64_a, 3); // CHECK: call <2 x i64> @llvm.mips.srlri.d(
- __msa_st_b(v16i8_b, &v16i8_a, 16); // CHECK: call void @llvm.mips.st.b(
- __msa_st_h(v8i16_b, &v8i16_a, 32); // CHECK: call void @llvm.mips.st.h(
- __msa_st_w(v4i32_b, &v4i32_a, 48); // CHECK: call void @llvm.mips.st.w(
- __msa_st_d(v2i64_b, &v2i64_a, 96); // CHECK: call void @llvm.mips.st.d(
+ __msa_st_b(v16i8_b, &v16i8_a, 1); // CHECK: call void @llvm.mips.st.b(
+ __msa_st_h(v8i16_b, &v8i16_a, 2); // CHECK: call void @llvm.mips.st.h(
+ __msa_st_w(v4i32_b, &v4i32_a, 4); // CHECK: call void @llvm.mips.st.w(
+ __msa_st_d(v2i64_b, &v2i64_a, 8); // CHECK: call void @llvm.mips.st.d(
v16i8_r = __msa_subs_s_b(v16i8_a, v16i8_b); // CHECK: call <16 x i8> @llvm.mips.subs.s.b(
v8i16_r = __msa_subs_s_h(v8i16_a, v8i16_b); // CHECK: call <8 x i16> @llvm.mips.subs.s.h(
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
index 99cf3c2538..13562354f4 100644
--- a/test/CodeGen/builtins-ppc-altivec.c
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -4256,52 +4256,76 @@ void test6() {
/* vec_sr */
res_vsc = vec_sr(vsc, vuc);
-// CHECK: lshr <16 x i8>
-// CHECK-LE: lshr <16 x i8>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK-LE: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vuc = vec_sr(vuc, vuc);
-// CHECK: lshr <16 x i8>
-// CHECK-LE: lshr <16 x i8>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK-LE: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vs = vec_sr(vs, vus);
-// CHECK: lshr <8 x i16>
-// CHECK-LE: lshr <8 x i16>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK-LE: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vus = vec_sr(vus, vus);
-// CHECK: lshr <8 x i16>
-// CHECK-LE: lshr <8 x i16>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK-LE: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vi = vec_sr(vi, vui);
-// CHECK: lshr <4 x i32>
-// CHECK-LE: lshr <4 x i32>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK-LE: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vui = vec_sr(vui, vui);
-// CHECK: lshr <4 x i32>
-// CHECK-LE: lshr <4 x i32>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK-LE: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vsc = vec_vsrb(vsc, vuc);
-// CHECK: shr <16 x i8>
-// CHECK-LE: shr <16 x i8>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK-LE: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vuc = vec_vsrb(vuc, vuc);
-// CHECK: shr <16 x i8>
-// CHECK-LE: shr <16 x i8>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK-LE: lshr <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vs = vec_vsrh(vs, vus);
-// CHECK: shr <8 x i16>
-// CHECK-LE: shr <8 x i16>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK-LE: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vus = vec_vsrh(vus, vus);
-// CHECK: shr <8 x i16>
-// CHECK-LE: shr <8 x i16>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK-LE: lshr <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vi = vec_vsrw(vi, vui);
-// CHECK: shr <4 x i32>
-// CHECK-LE: shr <4 x i32>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK-LE: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
res_vui = vec_vsrw(vui, vui);
-// CHECK: shr <4 x i32>
-// CHECK-LE: shr <4 x i32>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK-LE: lshr <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
/* vec_sra */
res_vsc = vec_sra(vsc, vuc);
@@ -9338,32 +9362,32 @@ void test9() {
// CHECK-LABEL: define void @test9
// CHECK-LE-LABEL: define void @test9
res_vsc = vec_xl(param_sll, &param_sc);
- // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1
res_vuc = vec_xl(param_sll, &param_uc);
- // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1
res_vs = vec_xl(param_sll, &param_s);
- // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1
res_vus = vec_xl(param_sll, &param_us);
- // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1
res_vi = vec_xl(param_sll, &param_i);
- // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1
res_vui = vec_xl(param_sll, &param_ui);
- // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1
res_vf = vec_xl(param_sll, &param_f);
- // CHECK: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 16
+ // CHECK: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 1
}
/* ------------------------------ vec_xst ----------------------------------- */
@@ -9371,32 +9395,32 @@ void test10() {
// CHECK-LABEL: define void @test10
// CHECK-LE-LABEL: define void @test10
vec_xst(vsc, param_sll, &param_sc);
- // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 1
vec_xst(vuc, param_sll, &param_uc);
- // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 1
vec_xst(vs, param_sll, &param_s);
- // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 1
vec_xst(vus, param_sll, &param_us);
- // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 1
vec_xst(vi, param_sll, &param_i);
- // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 1
vec_xst(vui, param_sll, &param_ui);
- // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 1
vec_xst(vf, param_sll, &param_f);
- // CHECK: store <4 x float> %{{[0-9]+}}, <4 x float>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <4 x float> %{{[0-9]+}}, <4 x float>* %{{[0-9]+}}, align 16
+ // CHECK: store <4 x float> %{{[0-9]+}}, <4 x float>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <4 x float> %{{[0-9]+}}, <4 x float>* %{{[0-9]+}}, align 1
}
/* ----------------------------- vec_xl_be ---------------------------------- */
@@ -9404,35 +9428,35 @@ void test11() {
// CHECK-LABEL: define void @test11
// CHECK-LE-LABEL: define void @test11
res_vsc = vec_xl_be(param_sll, &param_sc);
- // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
// CHECK-LE: shufflevector <16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}}, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>
res_vuc = vec_xl_be(param_sll, &param_uc);
- // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
// CHECK-LE: shufflevector <16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}}, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>
res_vs = vec_xl_be(param_sll, &param_s);
- // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
// CHECK-LE: shufflevector <8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}}, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
res_vus = vec_xl_be(param_sll, &param_us);
- // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
// CHECK-LE: shufflevector <8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}}, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
res_vi = vec_xl_be(param_sll, &param_i);
- // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1
// CHECK-LE: call <4 x i32> @llvm.ppc.vsx.lxvw4x.be(i8* %{{[0-9]+}})
res_vui = vec_xl_be(param_sll, &param_ui);
- // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1
// CHECK-LE: call <4 x i32> @llvm.ppc.vsx.lxvw4x.be(i8* %{{[0-9]+}})
res_vf = vec_xl_be(param_sll, &param_f);
- // CHECK: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 16
+ // CHECK: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 1
// CHECK-LE: call <4 x i32> @llvm.ppc.vsx.lxvw4x.be(i8* %{{[0-9]+}})
}
@@ -9441,34 +9465,34 @@ void test12() {
// CHECK-LABEL: define void @test12
// CHECK-LE-LABEL: define void @test12
vec_xst_be(vsc, param_sll, &param_sc);
- // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 1
// CHECK-LE: shufflevector <16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}}, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vuc, param_sll, &param_uc);
- // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 16
+ // CHECK: store <16 x i8> %{{[0-9]+}}, <16 x i8>* %{{[0-9]+}}, align 1
// CHECK-LE: shufflevector <16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}}, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vs, param_sll, &param_s);
- // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 1
// CHECK-LE: shufflevector <8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}}, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vus, param_sll, &param_us);
- // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 16
+ // CHECK: store <8 x i16> %{{[0-9]+}}, <8 x i16>* %{{[0-9]+}}, align 1
// CHECK-LE: shufflevector <8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}}, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vi, param_sll, &param_i);
- // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 1
// CHECK-LE: call void @llvm.ppc.vsx.stxvw4x.be(<4 x i32> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vui, param_sll, &param_ui);
- // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 16
+ // CHECK: store <4 x i32> %{{[0-9]+}}, <4 x i32>* %{{[0-9]+}}, align 1
// CHECK-LE: call void @llvm.ppc.vsx.stxvw4x.be(<4 x i32> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vf, param_sll, &param_f);
- // CHECK: store <4 x float> %{{[0-9]+}}, <4 x float>* %{{[0-9]+}}, align 16
+ // CHECK: store <4 x float> %{{[0-9]+}}, <4 x float>* %{{[0-9]+}}, align 1
// CHECK-LE: call void @llvm.ppc.vsx.stxvw4x.be(<4 x i32> %{{[0-9]+}}, i8* %{{[0-9]+}})
}
diff --git a/test/CodeGen/builtins-ppc-p8vector.c b/test/CodeGen/builtins-ppc-p8vector.c
index 9f2913847e..a686b0a079 100644
--- a/test/CodeGen/builtins-ppc-p8vector.c
+++ b/test/CodeGen/builtins-ppc-p8vector.c
@@ -1066,13 +1066,17 @@ void test1() {
/* vec_sr */
res_vsll = vec_sr(vsll, vull);
-// CHECK: lshr <2 x i64>
-// CHECK-LE: lshr <2 x i64>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <2 x i64> {{[0-9a-zA-Z%.]+}}, <i64 64, i64 64>
+// CHECK: lshr <2 x i64> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <2 x i64> {{[0-9a-zA-Z%.]+}}, <i64 64, i64 64>
+// CHECK-LE: lshr <2 x i64> {{[0-9a-zA-Z%.]+}}, [[UREM]]
// CHECK-PPC: error: call to 'vec_sr' is ambiguous
res_vull = vec_sr(vull, vull);
-// CHECK: lshr <2 x i64>
-// CHECK-LE: lshr <2 x i64>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <2 x i64> {{[0-9a-zA-Z%.]+}}, <i64 64, i64 64>
+// CHECK: lshr <2 x i64> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <2 x i64> {{[0-9a-zA-Z%.]+}}, <i64 64, i64 64>
+// CHECK-LE: lshr <2 x i64> {{[0-9a-zA-Z%.]+}}, [[UREM]]
// CHECK-PPC: error: call to 'vec_sr' is ambiguous
/* vec_sra */
diff --git a/test/CodeGen/builtins-ppc-quadword.c b/test/CodeGen/builtins-ppc-quadword.c
index 7d014db613..868fb183a6 100644
--- a/test/CodeGen/builtins-ppc-quadword.c
+++ b/test/CodeGen/builtins-ppc-quadword.c
@@ -205,45 +205,45 @@ void test1() {
/* vec_xl */
res_vlll = vec_xl(param_sll, &param_lll);
- // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xl' is ambiguous
res_vulll = vec_xl(param_sll, &param_ulll);
- // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xl' is ambiguous
/* vec_xst */
vec_xst(vlll, param_sll, &param_lll);
- // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xst' is ambiguous
vec_xst(vulll, param_sll, &param_ulll);
- // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xst' is ambiguous
/* vec_xl_be */
res_vlll = vec_xl_be(param_sll, &param_lll);
- // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xl' is ambiguous
res_vulll = vec_xl_be(param_sll, &param_ulll);
- // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: load <1 x i128>, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xl' is ambiguous
/* vec_xst_be */
vec_xst_be(vlll, param_sll, &param_lll);
- // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xst' is ambiguous
vec_xst_be(vulll, param_sll, &param_ulll);
- // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
- // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 16
+ // CHECK: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
+ // CHECK-LE: store <1 x i128> %{{[0-9]+}}, <1 x i128>* %{{[0-9]+}}, align 1
// CHECK-PPC: error: call to 'vec_xst' is ambiguous
}
diff --git a/test/CodeGen/builtins-ppc-vsx.c b/test/CodeGen/builtins-ppc-vsx.c
index c19140b946..838d94cf7d 100644
--- a/test/CodeGen/builtins-ppc-vsx.c
+++ b/test/CodeGen/builtins-ppc-vsx.c
@@ -1638,51 +1638,51 @@ res_vsll = vec_slo(vsll, vsc);
// CHECK-LE: @llvm.ppc.altivec.vsro
res_vsll = vec_xl(sll, asll);
-// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 16
-// CHECK-LE: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 1
+// CHECK-LE: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 1
res_vull = vec_xl(sll, aull);
-// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 16
-// CHECK-LE: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 1
+// CHECK-LE: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 1
res_vd = vec_xl(sll, ad);
-// CHECK: load <2 x double>, <2 x double>* %{{[0-9]+}}, align 16
-// CHECK-LE: load <2 x double>, <2 x double>* %{{[0-9]+}}, align 16
+// CHECK: load <2 x double>, <2 x double>* %{{[0-9]+}}, align 1
+// CHECK-LE: load <2 x double>, <2 x double>* %{{[0-9]+}}, align 1
vec_xst(vsll, sll, asll);
-// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 16
-// CHECK-LE: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 1
+// CHECK-LE: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 1
vec_xst(vull, sll, aull);
-// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 16
-// CHECK-LE: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 1
+// CHECK-LE: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 1
vec_xst(vd, sll, ad);
-// CHECK: store <2 x double> %{{[0-9]+}}, <2 x double>* %{{[0-9]+}}, align 16
-// CHECK-LE: store <2 x double> %{{[0-9]+}}, <2 x double>* %{{[0-9]+}}, align 16
+// CHECK: store <2 x double> %{{[0-9]+}}, <2 x double>* %{{[0-9]+}}, align 1
+// CHECK-LE: store <2 x double> %{{[0-9]+}}, <2 x double>* %{{[0-9]+}}, align 1
res_vsll = vec_xl_be(sll, asll);
-// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
res_vull = vec_xl_be(sll, aull);
-// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: load <2 x i64>, <2 x i64>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
res_vd = vec_xl_be(sll, ad);
-// CHECK: load <2 x double>, <2 x double>* %{{[0-9]+}}, align 16
+// CHECK: load <2 x double>, <2 x double>* %{{[0-9]+}}, align 1
// CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}})
vec_xst_be(vsll, sll, asll);
-// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 1
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vull, sll, aull);
-// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 16
+// CHECK: store <2 x i64> %{{[0-9]+}}, <2 x i64>* %{{[0-9]+}}, align 1
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
vec_xst_be(vd, sll, ad);
-// CHECK: store <2 x double> %{{[0-9]+}}, <2 x double>* %{{[0-9]+}}, align 16
+// CHECK: store <2 x double> %{{[0-9]+}}, <2 x double>* %{{[0-9]+}}, align 1
// CHECK-LE: call void @llvm.ppc.vsx.stxvd2x.be(<2 x double> %{{[0-9]+}}, i8* %{{[0-9]+}})
res_vf = vec_neg(vf);
diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c
index 775bca374b..dce721ef5a 100644
--- a/test/CodeGen/builtins-wasm.c
+++ b/test/CodeGen/builtins-wasm.c
@@ -1,70 +1,434 @@
-// RUN: %clang_cc1 -triple wasm32-unknown-unknown -O3 -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY32
-// RUN: %clang_cc1 -triple wasm64-unknown-unknown -O3 -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY64
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fno-lax-vector-conversions \
+// RUN: -O3 -emit-llvm -o - %s \
+// RUN: | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -fno-lax-vector-conversions \
+// RUN: -O3 -emit-llvm -o - %s \
+// RUN: | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
-__SIZE_TYPE__ f0(void) {
+// SIMD convenience types
+typedef char i8x16 __attribute((vector_size(16)));
+typedef short i16x8 __attribute((vector_size(16)));
+typedef int i32x4 __attribute((vector_size(16)));
+typedef long long i64x2 __attribute((vector_size(16)));
+typedef unsigned char u8x16 __attribute((vector_size(16)));
+typedef unsigned short u16x8 __attribute((vector_size(16)));
+typedef unsigned int u32x4 __attribute((vector_size(16)));
+typedef unsigned long long u64x2 __attribute((vector_size(16)));
+typedef float f32x4 __attribute((vector_size(16)));
+typedef double f64x2 __attribute((vector_size(16)));
+
+__SIZE_TYPE__ memory_size(void) {
return __builtin_wasm_memory_size(0);
// WEBASSEMBLY32: call {{i.*}} @llvm.wasm.memory.size.i32(i32 0)
// WEBASSEMBLY64: call {{i.*}} @llvm.wasm.memory.size.i64(i32 0)
}
-__SIZE_TYPE__ f1(__SIZE_TYPE__ delta) {
+__SIZE_TYPE__ memory_grow(__SIZE_TYPE__ delta) {
return __builtin_wasm_memory_grow(0, delta);
// WEBASSEMBLY32: call i32 @llvm.wasm.memory.grow.i32(i32 0, i32 %{{.*}})
// WEBASSEMBLY64: call i64 @llvm.wasm.memory.grow.i64(i32 0, i64 %{{.*}})
}
-__SIZE_TYPE__ f2(void) {
+__SIZE_TYPE__ mem_size(void) {
return __builtin_wasm_mem_size(0);
// WEBASSEMBLY32: call {{i.*}} @llvm.wasm.mem.size.i32(i32 0)
// WEBASSEMBLY64: call {{i.*}} @llvm.wasm.mem.size.i64(i32 0)
}
-__SIZE_TYPE__ f3(__SIZE_TYPE__ delta) {
+__SIZE_TYPE__ mem_grow(__SIZE_TYPE__ delta) {
return __builtin_wasm_mem_grow(0, delta);
// WEBASSEMBLY32: call i32 @llvm.wasm.mem.grow.i32(i32 0, i32 %{{.*}})
// WEBASSEMBLY64: call i64 @llvm.wasm.mem.grow.i64(i32 0, i64 %{{.*}})
}
-__SIZE_TYPE__ f4(void) {
+__SIZE_TYPE__ current_memory(void) {
return __builtin_wasm_current_memory();
// WEBASSEMBLY32: call {{i.*}} @llvm.wasm.current.memory.i32()
// WEBASSEMBLY64: call {{i.*}} @llvm.wasm.current.memory.i64()
}
-__SIZE_TYPE__ f5(__SIZE_TYPE__ delta) {
+__SIZE_TYPE__ grow_memory(__SIZE_TYPE__ delta) {
return __builtin_wasm_grow_memory(delta);
// WEBASSEMBLY32: call i32 @llvm.wasm.grow.memory.i32(i32 %{{.*}})
// WEBASSEMBLY64: call i64 @llvm.wasm.grow.memory.i64(i64 %{{.*}})
}
-void f6(unsigned int tag, void *obj) {
+void throw(unsigned int tag, void *obj) {
return __builtin_wasm_throw(tag, obj);
// WEBASSEMBLY32: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}})
// WEBASSEMBLY64: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}})
}
-void f7(void) {
+void rethrow(void) {
return __builtin_wasm_rethrow();
// WEBASSEMBLY32: call void @llvm.wasm.rethrow()
// WEBASSEMBLY64: call void @llvm.wasm.rethrow()
}
-int f8(int *addr, int expected, long long timeout) {
+int atomic_wait_i32(int *addr, int expected, long long timeout) {
return __builtin_wasm_atomic_wait_i32(addr, expected, timeout);
// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
}
-int f9(long long *addr, long long expected, long long timeout) {
+int atomic_wait_i64(long long *addr, long long expected, long long timeout) {
return __builtin_wasm_atomic_wait_i64(addr, expected, timeout);
// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
}
-unsigned int f10(int *addr, int count) {
+unsigned int atomic_notify(int *addr, unsigned int count) {
return __builtin_wasm_atomic_notify(addr, count);
// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
}
+
+int trunc_saturate_s_i32_f32(float f) {
+ return __builtin_wasm_trunc_saturate_s_i32_f32(f);
+ // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int trunc_saturate_u_i32_f32(float f) {
+ return __builtin_wasm_trunc_saturate_u_i32_f32(f);
+ // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int trunc_saturate_s_i32_f64(double f) {
+ return __builtin_wasm_trunc_saturate_s_i32_f64(f);
+ // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int trunc_saturate_u_i32_f64(double f) {
+ return __builtin_wasm_trunc_saturate_u_i32_f64(f);
+ // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+long long trunc_saturate_s_i64_f32(float f) {
+ return __builtin_wasm_trunc_saturate_s_i64_f32(f);
+ // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+long long trunc_saturate_u_i64_f32(float f) {
+ return __builtin_wasm_trunc_saturate_u_i64_f32(f);
+ // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+long long trunc_saturate_s_i64_f64(double f) {
+ return __builtin_wasm_trunc_saturate_s_i64_f64(f);
+ // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+long long trunc_saturate_u_i64_f64(double f) {
+ return __builtin_wasm_trunc_saturate_u_i64_f64(f);
+ // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+float min_f32(float x, float y) {
+ return __builtin_wasm_min_f32(x, y);
+ // WEBASSEMBLY: call float @llvm.minimum.f32(float %x, float %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+float max_f32(float x, float y) {
+ return __builtin_wasm_max_f32(x, y);
+ // WEBASSEMBLY: call float @llvm.maximum.f32(float %x, float %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+double min_f64(double x, double y) {
+ return __builtin_wasm_min_f64(x, y);
+ // WEBASSEMBLY: call double @llvm.minimum.f64(double %x, double %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+double max_f64(double x, double y) {
+ return __builtin_wasm_max_f64(x, y);
+ // WEBASSEMBLY: call double @llvm.maximum.f64(double %x, double %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+
+int extract_lane_s_i8x16(i8x16 v) {
+ return __builtin_wasm_extract_lane_s_i8x16(v, 13);
+ // WEBASSEMBLY: extractelement <16 x i8> %v, i32 13
+ // WEBASSEMBLY-NEXT: sext
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int extract_lane_u_i8x16(i8x16 v) {
+ return __builtin_wasm_extract_lane_u_i8x16(v, 13);
+ // WEBASSEMBLY: extractelement <16 x i8> %v, i32 13
+ // WEBASSEMBLY-NEXT: zext
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int extract_lane_s_i16x8(i16x8 v) {
+ return __builtin_wasm_extract_lane_s_i16x8(v, 7);
+ // WEBASSEMBLY: extractelement <8 x i16> %v, i32 7
+ // WEBASSEMBLY-NEXT: sext
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int extract_lane_u_i16x8(i16x8 v) {
+ return __builtin_wasm_extract_lane_u_i16x8(v, 7);
+ // WEBASSEMBLY: extractelement <8 x i16> %v, i32 7
+ // WEBASSEMBLY-NEXT: zext
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int extract_lane_i32x4(i32x4 v) {
+ return __builtin_wasm_extract_lane_i32x4(v, 3);
+ // WEBASSEMBLY: extractelement <4 x i32> %v, i32 3
+ // WEBASSEMBLY-NEXT: ret
+}
+
+long long extract_lane_i64x2(i64x2 v) {
+ return __builtin_wasm_extract_lane_i64x2(v, 1);
+ // WEBASSEMBLY: extractelement <2 x i64> %v, i32 1
+ // WEBASSEMBLY-NEXT: ret
+}
+
+float extract_lane_f32x4(f32x4 v) {
+ return __builtin_wasm_extract_lane_f32x4(v, 3);
+ // WEBASSEMBLY: extractelement <4 x float> %v, i32 3
+ // WEBASSEMBLY-NEXT: ret
+}
+
+double extract_lane_f64x2(f64x2 v) {
+ return __builtin_wasm_extract_lane_f64x2(v, 1);
+ // WEBASSEMBLY: extractelement <2 x double> %v, i32 1
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i8x16 replace_lane_i8x16(i8x16 v, int x) {
+ return __builtin_wasm_replace_lane_i8x16(v, 13, x);
+ // WEBASSEMBLY: trunc i32 %x to i8
+ // WEBASSEMBLY-NEXT: insertelement <16 x i8> %v, i8 %{{.*}}, i32 13
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i16x8 replace_lane_i16x8(i16x8 v, int x) {
+ return __builtin_wasm_replace_lane_i16x8(v, 7, x);
+ // WEBASSEMBLY: trunc i32 %x to i16
+ // WEBASSEMBLY-NEXT: insertelement <8 x i16> %v, i16 %{{.*}}, i32 7
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i32x4 replace_lane_i32x4(i32x4 v, int x) {
+ return __builtin_wasm_replace_lane_i32x4(v, 3, x);
+ // WEBASSEMBLY: insertelement <4 x i32> %v, i32 %x, i32 3
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i64x2 replace_lane_i64x2(i64x2 v, long long x) {
+ return __builtin_wasm_replace_lane_i64x2(v, 1, x);
+ // WEBASSEMBLY: insertelement <2 x i64> %v, i64 %x, i32 1
+ // WEBASSEMBLY-NEXT: ret
+}
+
+f32x4 replace_lane_f32x4(f32x4 v, float x) {
+ return __builtin_wasm_replace_lane_f32x4(v, 3, x);
+ // WEBASSEMBLY: insertelement <4 x float> %v, float %x, i32 3
+ // WEBASSEMBLY-NEXT: ret
+}
+
+f64x2 replace_lane_f64x2(f64x2 v, double x) {
+ return __builtin_wasm_replace_lane_f64x2(v, 1, x);
+ // WEBASSEMBLY: insertelement <2 x double> %v, double %x, i32 1
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i8x16 add_saturate_s_i8x16(i8x16 x, i8x16 y) {
+ return __builtin_wasm_add_saturate_s_i8x16(x, y);
+ // WEBASSEMBLY: call <16 x i8> @llvm.sadd.sat.v16i8(
+ // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i8x16 add_saturate_u_i8x16(i8x16 x, i8x16 y) {
+ return __builtin_wasm_add_saturate_u_i8x16(x, y);
+ // WEBASSEMBLY: call <16 x i8> @llvm.uadd.sat.v16i8(
+ // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i16x8 add_saturate_s_i16x8(i16x8 x, i16x8 y) {
+ return __builtin_wasm_add_saturate_s_i16x8(x, y);
+ // WEBASSEMBLY: call <8 x i16> @llvm.sadd.sat.v8i16(
+ // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i16x8 add_saturate_u_i16x8(i16x8 x, i16x8 y) {
+ return __builtin_wasm_add_saturate_u_i16x8(x, y);
+ // WEBASSEMBLY: call <8 x i16> @llvm.uadd.sat.v8i16(
+ // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i8x16 sub_saturate_s_i8x16(i8x16 x, i8x16 y) {
+ return __builtin_wasm_sub_saturate_s_i8x16(x, y);
+ // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.saturate.signed.v16i8(
+ // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i8x16 sub_saturate_u_i8x16(i8x16 x, i8x16 y) {
+ return __builtin_wasm_sub_saturate_u_i8x16(x, y);
+ // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.saturate.unsigned.v16i8(
+ // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i16x8 sub_saturate_s_i16x8(i16x8 x, i16x8 y) {
+ return __builtin_wasm_sub_saturate_s_i16x8(x, y);
+ // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.saturate.signed.v8i16(
+ // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i16x8 sub_saturate_u_i16x8(i16x8 x, i16x8 y) {
+ return __builtin_wasm_sub_saturate_u_i16x8(x, y);
+ // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.saturate.unsigned.v8i16(
+ // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i32x4 bitselect(i32x4 x, i32x4 y, i32x4 c) {
+ return __builtin_wasm_bitselect(x, y, c);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.bitselect.v4i32(
+ // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y, <4 x i32> %c)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+int any_true_i8x16(i8x16 x) {
+ return __builtin_wasm_any_true_i8x16(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)
+ // WEBASSEMBLY: ret
+}
+
+int any_true_i16x8(i16x8 x) {
+ return __builtin_wasm_any_true_i16x8(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x)
+ // WEBASSEMBLY: ret
+}
+
+int any_true_i32x4(i32x4 x) {
+ return __builtin_wasm_any_true_i32x4(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x)
+ // WEBASSEMBLY: ret
+}
+
+int any_true_i64x2(i64x2 x) {
+ return __builtin_wasm_any_true_i64x2(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x)
+ // WEBASSEMBLY: ret
+}
+
+int all_true_i8x16(i8x16 x) {
+ return __builtin_wasm_all_true_i8x16(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x)
+ // WEBASSEMBLY: ret
+}
+
+int all_true_i16x8(i16x8 x) {
+ return __builtin_wasm_all_true_i16x8(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x)
+ // WEBASSEMBLY: ret
+}
+
+int all_true_i32x4(i32x4 x) {
+ return __builtin_wasm_all_true_i32x4(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x)
+ // WEBASSEMBLY: ret
+}
+
+int all_true_i64x2(i64x2 x) {
+ return __builtin_wasm_all_true_i64x2(x);
+ // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x)
+ // WEBASSEMBLY: ret
+}
+
+f32x4 abs_f32x4(f32x4 x) {
+ return __builtin_wasm_abs_f32x4(x);
+ // WEBASSEMBLY: call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
+ // WEBASSEMBLY: ret
+}
+
+f64x2 abs_f64x2(f64x2 x) {
+ return __builtin_wasm_abs_f64x2(x);
+ // WEBASSEMBLY: call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
+ // WEBASSEMBLY: ret
+}
+
+f32x4 min_f32x4(f32x4 x, f32x4 y) {
+ return __builtin_wasm_min_f32x4(x, y);
+ // WEBASSEMBLY: call <4 x float> @llvm.minimum.v4f32(
+ // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+f32x4 max_f32x4(f32x4 x, f32x4 y) {
+ return __builtin_wasm_max_f32x4(x, y);
+ // WEBASSEMBLY: call <4 x float> @llvm.maximum.v4f32(
+ // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+f64x2 min_f64x2(f64x2 x, f64x2 y) {
+ return __builtin_wasm_min_f64x2(x, y);
+ // WEBASSEMBLY: call <2 x double> @llvm.minimum.v2f64(
+ // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+f64x2 max_f64x2(f64x2 x, f64x2 y) {
+ return __builtin_wasm_max_f64x2(x, y);
+ // WEBASSEMBLY: call <2 x double> @llvm.maximum.v2f64(
+ // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+f32x4 sqrt_f32x4(f32x4 x) {
+ return __builtin_wasm_sqrt_f32x4(x);
+ // WEBASSEMBLY: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
+ // WEBASSEMBLY: ret
+}
+
+f64x2 sqrt_f64x2(f64x2 x) {
+ return __builtin_wasm_sqrt_f64x2(x);
+ // WEBASSEMBLY: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
+ // WEBASSEMBLY: ret
+}
+
+i32x4 trunc_saturate_s_i32x4_f32x4(f32x4 f) {
+ return __builtin_wasm_trunc_saturate_s_i32x4_f32x4(f);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float> %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i32x4 trunc_saturate_u_i32x4_f32x4(f32x4 f) {
+ return __builtin_wasm_trunc_saturate_u_i32x4_f32x4(f);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.unsigned.v4i32.v4f32(<4 x float> %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i64x2 trunc_saturate_s_i64x2_f64x2(f64x2 f) {
+ return __builtin_wasm_trunc_saturate_s_i64x2_f64x2(f);
+ // WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.signed.v2i64.v2f64(<2 x double> %f)
+ // WEBASSEMBLY-NEXT: ret
+}
+
+i64x2 trunc_saturate_u_i64x2_f64x2(f64x2 f) {
+ return __builtin_wasm_trunc_saturate_u_i64x2_f64x2(f);
+ // WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.unsigned.v2i64.v2f64(<2 x double> %f)
+ // WEBASSEMBLY-NEXT: ret
+}
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 77b479e4c1..8e0542a1a8 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -132,6 +132,8 @@ int main() {
R(extract_return_addr, (&N));
P(signbit, (1.0));
+ R(launder, (&N));
+
return 0;
}
@@ -396,6 +398,15 @@ long long test_builtin_readcyclecounter() {
return __builtin_readcyclecounter();
}
+/// __builtin_launder should be a NOP in C since there are no vtables.
+// CHECK-LABEL: define void @test_builtin_launder
+void test_builtin_launder(int *p) {
+ // CHECK: [[TMP:%.*]] = load i32*,
+ // CHECK-NOT: @llvm.launder
+ // CHECK: store i32* [[TMP]],
+ int *d = __builtin_launder(p);
+}
+
// Behavior of __builtin_os_log differs between platforms, so only test on X86
#ifdef __x86_64__
@@ -440,10 +451,36 @@ void test_builtin_os_log(void *buf, int i, const char *data) {
// CHECK: call void @__os_log_helper_1_2_1_8_34(
__builtin_os_log_format(buf, "%{ xyz, public }s", "abc");
- // The last privacy annotation in the string wins.
+ // CHECK: call void @__os_log_helper_1_3_1_8_33(
+ __builtin_os_log_format(buf, "%{ xyz, private }s", "abc");
+
+ // CHECK: call void @__os_log_helper_1_3_1_8_37(
+ __builtin_os_log_format(buf, "%{ xyz, sensitive }s", "abc");
+
+ // The strictest privacy annotation in the string wins.
// CHECK: call void @__os_log_helper_1_3_1_8_33(
__builtin_os_log_format(buf, "%{ private, public, private, public}s", "abc");
+
+ // CHECK: call void @__os_log_helper_1_3_1_8_37(
+ __builtin_os_log_format(buf, "%{ private, sensitive, private, public}s",
+ "abc");
+
+ // CHECK: store volatile i32 22, i32* %[[LEN]], align 4
+ len = __builtin_os_log_format_buffer_size("%{mask.xyz}s", "abc");
+
+ // CHECK: call void @__os_log_helper_1_2_2_8_112_8_34(i8* {{.*}}, i64 8026488
+ __builtin_os_log_format(buf, "%{mask.xyz, public}s", "abc");
+
+ // CHECK: call void @__os_log_helper_1_3_2_8_112_4_1(i8* {{.*}}, i64 8026488
+ __builtin_os_log_format(buf, "%{ mask.xyz, private }d", 11);
+
+ // Mask type is silently ignored.
+ // CHECK: call void @__os_log_helper_1_2_1_8_32(
+ __builtin_os_log_format(buf, "%{ mask. xyz }s", "abc");
+
+ // CHECK: call void @__os_log_helper_1_2_1_8_32(
+ __builtin_os_log_format(buf, "%{ mask.xy z }s", "abc");
}
// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49
@@ -729,25 +766,28 @@ void test_builtin_os_log_merge_helper1(void *buf, unsigned u, long long ll) {
// CHECK-LABEL: define void @test_builtin_os_log_errno
void test_builtin_os_log_errno() {
- // CHECK: %[[VLA:.*]] = alloca i8, i64 4, align 16
- // CHECK: call void @__os_log_helper_16_2_1_0_96(i8* %[[VLA]])
+ // CHECK-NOT: @stacksave
+ // CHECK: %[[BUF:.*]] = alloca [4 x i8], align 1
+ // CHECK: %[[DECAY:.*]] = getelementptr inbounds [4 x i8], [4 x i8]* %[[BUF]], i32 0, i32 0
+ // CHECK: call void @__os_log_helper_1_2_1_0_96(i8* %[[DECAY]])
+ // CHECK-NOT: @stackrestore
char buf[__builtin_os_log_format_buffer_size("%m")];
__builtin_os_log_format(buf, "%m");
}
-// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_16_2_1_0_96
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_0_96
// CHECK: (i8* %[[BUFFER:.*]])
// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
-// CHECK: store i8 2, i8* %[[SUMMARY]], align 16
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
-// CHECK: store i8 96, i8* %[[ARGDESCRIPTOR]], align 2
+// CHECK: store i8 96, i8* %[[ARGDESCRIPTOR]], align 1
// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
// CHECK: store i8 0, i8* %[[ARGSIZE]], align 1
// CHECK-NEXT: ret void
diff --git a/test/CodeGen/catch-implicit-conversions-basics.c b/test/CodeGen/catch-implicit-conversions-basics.c
new file mode 100644
index 0000000000..2af16e80c8
--- /dev/null
+++ b/test/CodeGen/catch-implicit-conversions-basics.c
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// Test plan:
+// * Two types - int and char
+// * Two signs - signed and unsigned
+// * Square that - we have input and output types.
+// Thus, there are total of (2*2)^2 == 16 tests.
+// These are all the possible variations/combinations of casts.
+// However, not all of them should result in the check.
+// So here, we *only* check which should and which should not result in checks.
+
+// CHECK-DAG: @[[LINE_500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+// CHECK-DAG: @[[LINE_900_SIGN_CHANGE:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1000_SIGN_CHANGE:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1200_SIGN_CHANGE:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1300_SIGN_CHANGE:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1400_SIGN_CHANGE:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 4 }
+// CHECK-DAG: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
+unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_char
+unsigned char convert_unsigned_char_to_unsigned_char(unsigned char x) {
+#line 200
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_int
+signed int convert_signed_int_to_signed_int(signed int x) {
+#line 300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_char
+signed char convert_signed_char_to_signed_char(signed char x) {
+#line 400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
+unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*)
+#line 500
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_int
+unsigned int convert_unsigned_char_to_unsigned_int(unsigned char x) {
+#line 600
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_int
+signed int convert_unsigned_char_to_signed_int(unsigned char x) {
+#line 700
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_int
+signed int convert_signed_char_to_signed_int(signed char x) {
+#line 800
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_int
+signed int convert_unsigned_int_to_signed_int(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*)
+#line 900
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_int
+unsigned int convert_signed_int_to_unsigned_int(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*)
+#line 1000
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_char
+unsigned char convert_signed_int_to_unsigned_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGNED_TRUNCATION]] to i8*)
+#line 1100
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_char
+unsigned char convert_signed_char_to_unsigned_char(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*)
+#line 1200
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_char
+signed char convert_unsigned_char_to_signed_char(unsigned char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*)
+#line 1300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_int
+unsigned int convert_signed_char_to_unsigned_int(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*)
+#line 1400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_char
+signed char convert_unsigned_int_to_signed_char(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*)
+#line 1500
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_char
+signed char convert_signed_int_to_signed_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*)
+#line 1600
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-integer-arithmetic-value-change-basics.c b/test/CodeGen/catch-implicit-integer-arithmetic-value-change-basics.c
new file mode 100644
index 0000000000..0ba16eb052
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-arithmetic-value-change-basics.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// Test plan:
+// * Two types - int and char
+// * Two signs - signed and unsigned
+// * Square that - we have input and output types.
+// Thus, there are total of (2*2)^2 == 16 tests.
+// These are all the possible variations/combinations of casts.
+// However, not all of them should result in the check.
+// So here, we *only* check which should and which should not result in checks.
+
+// CHECK-DAG: @[[LINE_900_SIGN_CHANGE:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1000_SIGN_CHANGE:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1200_SIGN_CHANGE:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1300_SIGN_CHANGE:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1400_SIGN_CHANGE:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 4 }
+// CHECK-DAG: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
+unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_char
+unsigned char convert_unsigned_char_to_unsigned_char(unsigned char x) {
+#line 200
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_int
+signed int convert_signed_int_to_signed_int(signed int x) {
+#line 300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_char
+signed char convert_signed_char_to_signed_char(signed char x) {
+#line 400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
+unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
+#line 500
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_int
+unsigned int convert_unsigned_char_to_unsigned_int(unsigned char x) {
+#line 600
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_int
+signed int convert_unsigned_char_to_signed_int(unsigned char x) {
+#line 700
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_int
+signed int convert_signed_char_to_signed_int(signed char x) {
+#line 800
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_int
+signed int convert_unsigned_int_to_signed_int(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*)
+#line 900
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_int
+unsigned int convert_signed_int_to_unsigned_int(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*)
+#line 1000
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_char
+unsigned char convert_signed_int_to_unsigned_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGNED_TRUNCATION]] to i8*)
+#line 1100
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_char
+unsigned char convert_signed_char_to_unsigned_char(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*)
+#line 1200
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_char
+signed char convert_unsigned_char_to_signed_char(unsigned char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*)
+#line 1300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_int
+unsigned int convert_signed_char_to_unsigned_int(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*)
+#line 1400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_char
+signed char convert_unsigned_int_to_signed_char(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*)
+#line 1500
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_char
+signed char convert_signed_int_to_signed_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*)
+#line 1600
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-integer-conversions-basics.c b/test/CodeGen/catch-implicit-integer-conversions-basics.c
index 987f54c551..2af16e80c8 100644
--- a/test/CodeGen/catch-implicit-integer-conversions-basics.c
+++ b/test/CodeGen/catch-implicit-integer-conversions-basics.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
// Test plan:
// * Two types - int and char
@@ -9,10 +9,15 @@
// However, not all of them should result in the check.
// So here, we *only* check which should and which should not result in checks.
-// CHECK-DAG: @[[LINE_500_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_1100_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_1500_TRUNCATION:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_1600_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 0 }
+// CHECK-DAG: @[[LINE_500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+// CHECK-DAG: @[[LINE_900_SIGN_CHANGE:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1000_SIGN_CHANGE:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1200_SIGN_CHANGE:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1300_SIGN_CHANGE:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1400_SIGN_CHANGE:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 4 }
+// CHECK-DAG: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 2 }
// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
@@ -40,7 +45,7 @@ signed char convert_signed_char_to_signed_char(signed char x) {
// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*)
#line 500
return x;
}
@@ -65,51 +70,56 @@ signed int convert_signed_char_to_signed_int(signed char x) {
// CHECK-LABEL: @convert_unsigned_int_to_signed_int
signed int convert_unsigned_int_to_signed_int(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*)
#line 900
return x;
}
// CHECK-LABEL: @convert_signed_int_to_unsigned_int
unsigned int convert_signed_int_to_unsigned_int(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*)
#line 1000
return x;
}
// CHECK-LABEL: @convert_signed_int_to_unsigned_char
unsigned char convert_signed_int_to_unsigned_char(signed int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGNED_TRUNCATION]] to i8*)
#line 1100
return x;
}
// CHECK-LABEL: @convert_signed_char_to_unsigned_char
unsigned char convert_signed_char_to_unsigned_char(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*)
#line 1200
return x;
}
// CHECK-LABEL: @convert_unsigned_char_to_signed_char
signed char convert_unsigned_char_to_signed_char(unsigned char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*)
#line 1300
return x;
}
// CHECK-LABEL: @convert_signed_char_to_unsigned_int
unsigned int convert_signed_char_to_unsigned_int(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*)
#line 1400
return x;
}
// CHECK-LABEL: @convert_unsigned_int_to_signed_char
signed char convert_unsigned_int_to_signed_char(unsigned int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*)
#line 1500
return x;
}
// CHECK-LABEL: @convert_signed_int_to_signed_char
signed char convert_signed_int_to_signed_char(signed int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*)
#line 1600
return x;
}
diff --git a/test/CodeGen/catch-implicit-integer-sign-changes-CompoundAssignOperator.c b/test/CodeGen/catch-implicit-integer-sign-changes-CompoundAssignOperator.c
new file mode 100644
index 0000000000..9a87760896
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-sign-changes-CompoundAssignOperator.c
@@ -0,0 +1,2561 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+
+// LHS can be of 2 types: unsigned char and signed char
+// RHS can be of 4 types: unsigned char, signed char, unsigned int, signed int.
+// Therefore there are total of 8 tests per group.
+
+// Also there are total of 10 compound operators (+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=)
+
+// CHECK-SANITIZE-ANYRECOVER: @[[INT:.*]] = {{.*}} c"'int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_SIGN_CHANGE:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_SIGN_CHANGE:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_SIGN_CHANGE:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_500_SIGN_CHANGE:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_600_SIGN_CHANGE:.*]] = {{.*}}, i32 600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_700_SIGN_CHANGE:.*]] = {{.*}}, i32 700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_800_SIGN_CHANGE:.*]] = {{.*}}, i32 800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_900_SIGN_CHANGE:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1000_SIGN_CHANGE:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1200_SIGN_CHANGE:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1300_SIGN_CHANGE:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1400_SIGN_CHANGE:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1500_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1600_SIGN_CHANGE:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1700_SIGN_CHANGE:.*]] = {{.*}}, i32 1700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1800_SIGN_CHANGE:.*]] = {{.*}}, i32 1800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2000_SIGN_CHANGE:.*]] = {{.*}}, i32 2000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2100_SIGN_CHANGE:.*]] = {{.*}}, i32 2100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2200_SIGN_CHANGE:.*]] = {{.*}}, i32 2200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2300_SIGN_CHANGE:.*]] = {{.*}}, i32 2300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2400_SIGN_CHANGE:.*]] = {{.*}}, i32 2400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2500_SIGN_CHANGE:.*]] = {{.*}}, i32 2500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2600_SIGN_CHANGE:.*]] = {{.*}}, i32 2600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2800_SIGN_CHANGE:.*]] = {{.*}}, i32 2800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2900_SIGN_CHANGE:.*]] = {{.*}}, i32 2900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3000_SIGN_CHANGE:.*]] = {{.*}}, i32 3000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3100_SIGN_CHANGE:.*]] = {{.*}}, i32 3100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3200_SIGN_CHANGE:.*]] = {{.*}}, i32 3200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3300_SIGN_CHANGE:.*]] = {{.*}}, i32 3300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3400_SIGN_CHANGE:.*]] = {{.*}}, i32 3400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3600_SIGN_CHANGE:.*]] = {{.*}}, i32 3600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3700_SIGN_CHANGE:.*]] = {{.*}}, i32 3700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3800_SIGN_CHANGE:.*]] = {{.*}}, i32 3800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3900_SIGN_CHANGE:.*]] = {{.*}}, i32 3900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4000_SIGN_CHANGE:.*]] = {{.*}}, i32 4000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4100_SIGN_CHANGE:.*]] = {{.*}}, i32 4100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4200_SIGN_CHANGE:.*]] = {{.*}}, i32 4200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4300_SIGN_CHANGE:.*]] = {{.*}}, i32 4300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4400_SIGN_CHANGE:.*]] = {{.*}}, i32 4400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4500_SIGN_CHANGE:.*]] = {{.*}}, i32 4500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4600_SIGN_CHANGE:.*]] = {{.*}}, i32 4600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4700_SIGN_CHANGE:.*]] = {{.*}}, i32 4700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4800_SIGN_CHANGE:.*]] = {{.*}}, i32 4800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4900_SIGN_CHANGE:.*]] = {{.*}}, i32 4900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5000_SIGN_CHANGE:.*]] = {{.*}}, i32 5000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5100_SIGN_CHANGE:.*]] = {{.*}}, i32 5100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5200_SIGN_CHANGE:.*]] = {{.*}}, i32 5200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5300_SIGN_CHANGE:.*]] = {{.*}}, i32 5300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5400_SIGN_CHANGE:.*]] = {{.*}}, i32 5400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5500_SIGN_CHANGE:.*]] = {{.*}}, i32 5500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5600_SIGN_CHANGE:.*]] = {{.*}}, i32 5600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5700_SIGN_CHANGE:.*]] = {{.*}}, i32 5700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5800_SIGN_CHANGE:.*]] = {{.*}}, i32 5800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6000_SIGN_CHANGE:.*]] = {{.*}}, i32 6000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6100_SIGN_CHANGE:.*]] = {{.*}}, i32 6100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6200_SIGN_CHANGE:.*]] = {{.*}}, i32 6200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6300_SIGN_CHANGE:.*]] = {{.*}}, i32 6300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6400_SIGN_CHANGE:.*]] = {{.*}}, i32 6400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6500_SIGN_CHANGE:.*]] = {{.*}}, i32 6500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6600_SIGN_CHANGE:.*]] = {{.*}}, i32 6600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6800_SIGN_CHANGE:.*]] = {{.*}}, i32 6800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6900_SIGN_CHANGE:.*]] = {{.*}}, i32 6900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7000_SIGN_CHANGE:.*]] = {{.*}}, i32 7000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7100_SIGN_CHANGE:.*]] = {{.*}}, i32 7100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7200_SIGN_CHANGE:.*]] = {{.*}}, i32 7200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7300_SIGN_CHANGE:.*]] = {{.*}}, i32 7300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7400_SIGN_CHANGE:.*]] = {{.*}}, i32 7400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7600_SIGN_CHANGE:.*]] = {{.*}}, i32 7600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7700_SIGN_CHANGE:.*]] = {{.*}}, i32 7700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7800_SIGN_CHANGE:.*]] = {{.*}}, i32 7800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7900_SIGN_CHANGE:.*]] = {{.*}}, i32 7900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_8000_SIGN_CHANGE:.*]] = {{.*}}, i32 8000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+
+//----------------------------------------------------------------------------//
+// Compound add operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_unsigned_char
+void unsigned_char_add_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 100
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_signed_char
+void unsigned_char_add_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 200
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_unsigned_int
+void unsigned_char_add_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 300
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_signed_int
+void unsigned_char_add_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 400
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_unsigned_char
+void signed_char_add_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 500
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char
+void signed_char_add_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 600
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char_unsigned_int
+void signed_char_add_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 700
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char_signed_int
+void signed_char_add_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 800
+ (*LHS) += RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound subtract operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_unsigned_char
+void unsigned_char_sub_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 900
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_signed_char
+void unsigned_char_sub_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1000
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_unsigned_int
+void unsigned_char_sub_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 1100
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_signed_int
+void unsigned_char_sub_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1200
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_unsigned_char
+void signed_char_sub_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1300
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char
+void signed_char_sub_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1400
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char_unsigned_int
+void signed_char_sub_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1500
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char_signed_int
+void signed_char_sub_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1600
+ (*LHS) -= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound multiply operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_unsigned_char
+void unsigned_char_mul_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1700
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_signed_char
+void unsigned_char_mul_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1800
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_unsigned_int
+void unsigned_char_mul_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 1900
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_signed_int
+void unsigned_char_mul_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2000
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_unsigned_char
+void signed_char_mul_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2100
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char
+void signed_char_mul_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2200
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char_unsigned_int
+void signed_char_mul_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2300
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char_signed_int
+void signed_char_mul_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2400
+ (*LHS) *= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound divide operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_unsigned_char
+void unsigned_char_div_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2500
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_signed_char
+void unsigned_char_div_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2600
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_unsigned_int
+void unsigned_char_div_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 2700
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_signed_int
+void unsigned_char_div_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2800
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_unsigned_char
+void signed_char_div_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2900
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char
+void signed_char_div_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3000
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char_unsigned_int
+void signed_char_div_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = udiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3100
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char_signed_int
+void signed_char_div_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3200
+ (*LHS) /= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound remainder operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_unsigned_char
+void unsigned_char_rem_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3300
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_signed_char
+void unsigned_char_rem_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3400
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_unsigned_int
+void unsigned_char_rem_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 3500
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_signed_int
+void unsigned_char_rem_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3600
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_unsigned_char
+void signed_char_rem_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3700
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char
+void signed_char_rem_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3800
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char_unsigned_int
+void signed_char_rem_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = urem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3900
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char_signed_int
+void signed_char_rem_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4000
+ (*LHS) %= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound left-shift operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_unsigned_char
+void unsigned_char_shl_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4100
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_signed_char
+void unsigned_char_shl_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4200
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_unsigned_int
+void unsigned_char_shl_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4300
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_signed_int
+void unsigned_char_shl_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4400
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_unsigned_char
+void signed_char_shl_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4500
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char
+void signed_char_shl_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4600
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char_unsigned_int
+void signed_char_shl_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4700
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char_signed_int
+void signed_char_shl_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4800
+ (*LHS) <<= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound right-shift operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_unsigned_char
+void unsigned_char_shr_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4900
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_signed_char
+void unsigned_char_shr_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5000
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_unsigned_int
+void unsigned_char_shr_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5100
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_signed_int
+void unsigned_char_shr_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5200
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_unsigned_char
+void signed_char_shr_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5300
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char
+void signed_char_shr_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5400
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char_unsigned_int
+void signed_char_shr_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5500
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char_signed_int
+void signed_char_shr_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5600
+ (*LHS) >>= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound and operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_unsigned_char
+void unsigned_char_and_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5700
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_signed_char
+void unsigned_char_and_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5800
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_unsigned_int
+void unsigned_char_and_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 5900
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_signed_int
+void unsigned_char_and_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6000
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_unsigned_char
+void signed_char_and_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6100
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char
+void signed_char_and_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6200
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char_unsigned_int
+void signed_char_and_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6300
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char_signed_int
+void signed_char_and_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6400
+ (*LHS) &= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound xor operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_unsigned_char
+void unsigned_char_or_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6500_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6500
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_signed_char
+void unsigned_char_or_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6600
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_unsigned_int
+void unsigned_char_or_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 6700
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_signed_int
+void unsigned_char_or_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6800
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_unsigned_char
+void signed_char_or_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6900
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char
+void signed_char_or_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7000
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char_unsigned_int
+void signed_char_or_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7100_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7100
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char_signed_int
+void signed_char_or_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7200
+ (*LHS) |= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound or operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_unsigned_char
+void unsigned_char_xor_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7300
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_signed_char
+void unsigned_char_xor_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7400_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7400
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_unsigned_int
+void unsigned_char_xor_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 7500
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_signed_int
+void unsigned_char_xor_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7600_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7600
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_unsigned_char
+void signed_char_xor_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7700_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7700
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char
+void signed_char_xor_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7800_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7800
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char_unsigned_int
+void signed_char_xor_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7900_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7900
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char_signed_int
+void signed_char_xor_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[SRC]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_8000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_8000_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 8000
+ (*LHS) ^= RHS;
+}
diff --git a/test/CodeGen/catch-implicit-integer-sign-changes-basics.c b/test/CodeGen/catch-implicit-integer-sign-changes-basics.c
new file mode 100644
index 0000000000..71533a9b92
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-sign-changes-basics.c
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// Test plan:
+// * Two types - int and char
+// * Two signs - signed and unsigned
+// * Square that - we have input and output types.
+// Thus, there are total of (2*2)^2 == 16 tests.
+// These are all the possible variations/combinations of casts.
+// However, not all of them should result in the check.
+// So here, we *only* check which should and which should not result in checks.
+
+// CHECK-DAG: @[[LINE_900_SIGN_CHANGE:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1000_SIGN_CHANGE:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1100_SIGN_CHANGE:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1200_SIGN_CHANGE:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1300_SIGN_CHANGE:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1400_SIGN_CHANGE:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1500_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+// CHECK-DAG: @[[LINE_1600_SIGN_CHANGE:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 3 }
+
+//============================================================================//
+// Half of the cases do not need the check. //
+//============================================================================//
+
+//----------------------------------------------------------------------------//
+// No cast happens at all. No check needed.
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
+unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_char
+unsigned char convert_unsigned_char_to_unsigned_char(unsigned char x) {
+#line 200
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_int
+signed int convert_signed_int_to_signed_int(signed int x) {
+#line 300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_char
+signed char convert_signed_char_to_signed_char(signed char x) {
+#line 400
+ return x;
+}
+
+//----------------------------------------------------------------------------//
+// Both types are unsigned. No check needed.
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
+unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
+#line 500
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_int
+unsigned int convert_unsigned_char_to_unsigned_int(unsigned char x) {
+#line 600
+ return x;
+}
+
+//----------------------------------------------------------------------------//
+// Source type was unsigned, destination type is signed, but non-negative.
+// Because zero-extension happens - the sign bit will be 0. No check needed.
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_int
+signed int convert_unsigned_char_to_signed_int(unsigned char x) {
+#line 700
+ return x;
+}
+
+//----------------------------------------------------------------------------//
+// Both types are signed, and have the same sign, since sign-extension happens,
+// i.e. the sign bit will be propagated. No check needed.
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @convert_signed_char_to_signed_int
+signed int convert_signed_char_to_signed_int(signed char x) {
+#line 800
+ return x;
+}
+
+//============================================================================//
+// The remaining 8 cases *do* need the check. //
+//============================================================================//
+
+// These 3 result in simple 'icmp sge i32 %x, 0'
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_int
+signed int convert_unsigned_int_to_signed_int(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*)
+#line 900
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_int
+unsigned int convert_signed_int_to_unsigned_int(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*)
+#line 1000
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_char
+unsigned char convert_signed_int_to_unsigned_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGN_CHANGE]] to i8*)
+#line 1100
+ return x;
+}
+
+// These 3 result in simple 'icmp sge i8 %x, 0'
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_char
+unsigned char convert_signed_char_to_unsigned_char(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*)
+#line 1200
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_char
+signed char convert_unsigned_char_to_signed_char(unsigned char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*)
+#line 1300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_int
+unsigned int convert_signed_char_to_unsigned_int(signed char x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*)
+#line 1400
+ return x;
+}
+
+// 'icmp sge i8 (trunc i32 %x), 0'
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_char
+signed char convert_unsigned_int_to_signed_char(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGN_CHANGE]] to i8*)
+#line 1500
+ return x;
+}
+
+// 'xor i1 (icmp sge i8 (trunc i32 %x), 0), (icmp sge i32 %x, 0)'
+
+// CHECK-LABEL: @convert_signed_int_to_signed_char
+signed char convert_signed_int_to_signed_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGN_CHANGE]] to i8*)
+#line 1600
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-integer-sign-changes-true-negatives.c b/test/CodeGen/catch-implicit-integer-sign-changes-true-negatives.c
new file mode 100644
index 0000000000..b847344818
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-sign-changes-true-negatives.c
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+
+// ========================================================================== //
+// The expected true-negatives.
+// ========================================================================== //
+
+// Sanitization is explicitly disabled.
+// ========================================================================== //
+
+// CHECK-LABEL: @blacklist_0
+__attribute__((no_sanitize("undefined"))) unsigned int blacklist_0(signed int src) {
+ // We are not in "undefined" group, so that doesn't work.
+ // CHECK-SANITIZE: call
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_1
+__attribute__((no_sanitize("integer"))) unsigned int blacklist_1(signed int src) {
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_2
+__attribute__((no_sanitize("implicit-conversion"))) unsigned int blacklist_2(signed int src) {
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_3
+__attribute__((no_sanitize("implicit-integer-sign-change"))) unsigned int blacklist_3(signed int src) {
+ return src;
+}
+
+// Explicit sign-changing conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: explicit_signed_int_to_unsigned_int
+unsigned int explicit_signed_int_to_unsigned_int(signed int src) {
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: explicit_unsigned_int_to_signed_int
+signed int explicit_unsigned_int_to_signed_int(unsigned int src) {
+ return (signed int)src;
+}
+
+// Explicit NOP conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_ununsigned_int_to_ununsigned_int
+unsigned int explicit_ununsigned_int_to_ununsigned_int(unsigned int src) {
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
+signed int explicit_unsigned_int_to_unsigned_int(signed int src) {
+ return (signed int)src;
+}
+
+// conversions to to boolean type are not counted as sign-change.
+// ========================================================================== //
+
+// CHECK-LABEL: @unsigned_int_to_bool
+_Bool unsigned_int_to_bool(unsigned int src) {
+ return src;
+}
+
+// CHECK-LABEL: @signed_int_to_bool
+_Bool signed_int_to_bool(signed int src) {
+ return src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_bool
+_Bool explicit_unsigned_int_to_bool(unsigned int src) {
+ return (_Bool)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_bool
+_Bool explicit_signed_int_to_bool(signed int src) {
+ return (_Bool)src;
+}
+
+// Explicit conversions from pointer to an integer.
+// Can not have an implicit conversion from pointer to an integer.
+// Can not have an implicit conversion between two enums.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_voidptr_to_unsigned_int
+unsigned int explicit_voidptr_to_unsigned_int(void *src) {
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_voidptr_to_signed_int
+signed int explicit_voidptr_to_signed_int(void *src) {
+ return (signed int)src;
+}
+
+// Implicit conversions from floating-point.
+// ========================================================================== //
+
+// CHECK-LABEL: @float_to_unsigned_int
+unsigned int float_to_unsigned_int(float src) {
+ return src;
+}
+
+// CHECK-LABEL: @float_to_signed_int
+signed int float_to_signed_int(float src) {
+ return src;
+}
+
+// CHECK-LABEL: @double_to_unsigned_int
+unsigned int double_to_unsigned_int(double src) {
+ return src;
+}
+
+// CHECK-LABEL: @double_to_signed_int
+signed int double_to_signed_int(double src) {
+ return src;
+}
+
+// Sugar.
+// ========================================================================== //
+
+typedef unsigned int uint32_t;
+
+// CHECK-LABEL: @uint32_to_unsigned_int
+unsigned int uint32_to_unsigned_int(uint32_t src) {
+ return src;
+}
+
+// CHECK-LABEL: @unsigned_int_to_uint32
+uint32_t unsigned_int_to_uint32(unsigned int src) {
+ return src;
+}
+
+// CHECK-LABEL: @uint32_to_uint32
+uint32_t uint32_to_uint32(uint32_t src) {
+ return src;
+}
+
+// "Transparent" Enum.
+// ========================================================================== //
+
+enum a { b = ~2147483647 };
+enum a c();
+void d(int);
+void e();
+void e() {
+ enum a f = c();
+ d(f);
+}
diff --git a/test/CodeGen/catch-implicit-integer-sign-changes.c b/test/CodeGen/catch-implicit-integer-sign-changes.c
new file mode 100644
index 0000000000..e1719048f1
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-sign-changes.c
@@ -0,0 +1,273 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[SIGNED_INT:.*]] = {{.*}} c"'int'\00" }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_100:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_INT]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_INT]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[SIGNED_CHAR]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[UNSIGNED_CHAR]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 10 }, {{.*}}* @[[SIGNED_CHAR]], {{.*}}* @[[UNSIGNED_INT]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER: @[[UINT32:.*]] = {{.*}} c"'uint32_t' (aka 'unsigned int')\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[INT32:.*]] = {{.*}} c"'int32_t' (aka 'int')\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}* @[[UINT32]], {{.*}}* @[[INT32]], i8 3 }
+
+// ========================================================================== //
+// The expected true-positives.
+// These are implicit, potentially sign-altering, conversions.
+// ========================================================================== //
+
+// These 3 result (after optimizations) in simple 'icmp sge i32 %src, 0'.
+
+// CHECK-LABEL: @unsigned_int_to_signed_int
+// CHECK-SAME: (i32 %[[SRC:.*]])
+signed int unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i32 %[[DST]]
+ // CHECK-NEXT: }
+#line 100
+ return src;
+}
+
+// CHECK-LABEL: @signed_int_to_unsigned_int
+// CHECK-SAME: (i32 %[[SRC:.*]])
+unsigned int signed_int_to_unsigned_int(signed int src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i32 %[[DST]]
+ // CHECK-NEXT: }
+#line 200
+ return src;
+}
+
+// CHECK-LABEL: @signed_int_to_unsigned_char
+// CHECK-SAME: (i32 %[[SRC:.*]])
+unsigned char signed_int_to_unsigned_char(signed int src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 300
+ return src;
+}
+
+// These 3 result (after optimizations) in simple 'icmp sge i8 %src, 0'
+
+// CHECK-LABEL: @signed_char_to_unsigned_char
+// CHECK-SAME: (i8 signext %[[SRC:.*]])
+unsigned char signed_char_to_unsigned_char(signed char src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i8
+ // CHECK-NEXT: store i8 %[[SRC]], i8* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i8, i8* %[[SRC_ADDR]]
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[DST]]
+ // CHECK-NEXT: }
+#line 400
+ return src;
+}
+
+// CHECK-LABEL: @unsigned_char_to_signed_char
+// CHECK-SAME: (i8 zeroext %[[SRC:.*]])
+signed char unsigned_char_to_signed_char(unsigned char src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i8
+ // CHECK-NEXT: store i8 %[[SRC]], i8* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i8, i8* %[[SRC_ADDR]]
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[DST]]
+ // CHECK-NEXT: }
+#line 500
+ return src;
+}
+
+// CHECK-LABEL: @signed_char_to_unsigned_int
+// CHECK-SAME: (i8 signext %[[SRC:.*]])
+unsigned int signed_char_to_unsigned_int(signed char src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i8
+ // CHECK-NEXT: store i8 %[[SRC]], i8* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i8, i8* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = sext i8 %[[DST]] to i32
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i32 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i32 %[[CONV]]
+ // CHECK-NEXT: }
+#line 600
+ return src;
+}
+
+// This one result (after optimizations) in 'icmp sge i8 (trunc i32 %src), 0'
+
+// CHECK-LABEL: @unsigned_int_to_signed_char
+// CHECK-SAME: (i32 %[[SRC:.*]])
+signed char unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 700
+ return src;
+}
+
+// The worst one: 'xor i1 (icmp sge i8 (trunc i32 %x), 0), (icmp sge i32 %x, 0)'
+
+// CHECK-LABEL: @signed_int_to_signed_char
+// CHECK-SAME: (i32 %[[SRC:.*]])
+signed char signed_int_to_signed_char(signed int x) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 800
+ return x;
+}
+
+// ========================================================================== //
+// Check canonical type stuff
+// ========================================================================== //
+
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+
+// CHECK-LABEL: @uint32_t_to_int32_t
+// CHECK-SAME: (i32 %[[SRC:.*]])
+int32_t uint32_t_to_int32_t(uint32_t src) {
+ // CHECK: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i32 %[[DST]]
+ // CHECK-NEXT: }
+#line 900
+ return src;
+}
+
+// ========================================================================== //
+// Check that explicit conversion does not interfere with implicit conversion
+// ========================================================================== //
+// These contain one implicit and one explicit sign-changing conversion.
+// We want to make sure that we still diagnose the implicit conversion.
+
+// Implicit sign-change after explicit sign-change.
+// CHECK-LABEL: @explicit_conversion_interference0
+unsigned int explicit_conversion_interference0(unsigned int c) {
+ // CHECK-SANITIZE: call
+ return (signed int)c;
+}
+
+// Implicit sign-change before explicit sign-change.
+// CHECK-LABEL: @explicit_conversion_interference1
+unsigned int explicit_conversion_interference1(unsigned int c) {
+ // CHECK-SANITIZE: call
+ signed int b;
+ return (unsigned int)(b = c);
+}
diff --git a/test/CodeGen/catch-implicit-integer-truncations-CompoundAssignOperator.c b/test/CodeGen/catch-implicit-integer-truncations-CompoundAssignOperator.c
new file mode 100644
index 0000000000..50e7696032
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-truncations-CompoundAssignOperator.c
@@ -0,0 +1,2745 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+
+// LHS can be of 2 types: unsigned char and signed char
+// RHS can be of 4 types: unsigned char, signed char, unsigned int, signed int.
+// Therefore there are total of 8 tests per group.
+
+// Also there are total of 10 compound operators (+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=)
+
+// CHECK-SANITIZE-ANYRECOVER: @[[INT:.*]] = {{.*}} c"'int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_300_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1100_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1900_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 1900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2700_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 2700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 3500, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5900_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 5900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6700_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 6700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 7500, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_8000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 8000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+//----------------------------------------------------------------------------//
+// Compound add operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_unsigned_char
+void unsigned_char_add_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 100
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_signed_char
+void unsigned_char_add_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 200
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_unsigned_int
+void unsigned_char_add_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 300
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_signed_int
+void unsigned_char_add_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 400
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_unsigned_char
+void signed_char_add_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 500
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char
+void signed_char_add_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 600
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char_unsigned_int
+void signed_char_add_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 700
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char_signed_int
+void signed_char_add_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 800
+ (*LHS) += RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound subtract operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_unsigned_char
+void unsigned_char_sub_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 900
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_signed_char
+void unsigned_char_sub_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1000
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_unsigned_int
+void unsigned_char_sub_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1100
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_signed_int
+void unsigned_char_sub_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1200
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_unsigned_char
+void signed_char_sub_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1300
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char
+void signed_char_sub_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1400
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char_unsigned_int
+void signed_char_sub_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1500
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char_signed_int
+void signed_char_sub_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1600
+ (*LHS) -= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound multiply operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_unsigned_char
+void unsigned_char_mul_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1700
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_signed_char
+void unsigned_char_mul_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1800
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_unsigned_int
+void unsigned_char_mul_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1900_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1900_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1900
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_signed_int
+void unsigned_char_mul_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2000
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_unsigned_char
+void signed_char_mul_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2100
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char
+void signed_char_mul_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2200
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char_unsigned_int
+void signed_char_mul_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2300
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char_signed_int
+void signed_char_mul_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2400
+ (*LHS) *= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound divide operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_unsigned_char
+void unsigned_char_div_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2500
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_signed_char
+void unsigned_char_div_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2600
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_unsigned_int
+void unsigned_char_div_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = udiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2700_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2700_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2700
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_signed_int
+void unsigned_char_div_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2800
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_unsigned_char
+void signed_char_div_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2900
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char
+void signed_char_div_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3000
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char_unsigned_int
+void signed_char_div_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = udiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3100
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char_signed_int
+void signed_char_div_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3200
+ (*LHS) /= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound remainder operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_unsigned_char
+void unsigned_char_rem_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3300
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_signed_char
+void unsigned_char_rem_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3400
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_unsigned_int
+void unsigned_char_rem_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = urem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3500
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_signed_int
+void unsigned_char_rem_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3600
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_unsigned_char
+void signed_char_rem_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3700
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char
+void signed_char_rem_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3800
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char_unsigned_int
+void signed_char_rem_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = urem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3900
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char_signed_int
+void signed_char_rem_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4000
+ (*LHS) %= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound left-shift operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_unsigned_char
+void unsigned_char_shl_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4100
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_signed_char
+void unsigned_char_shl_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4200
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_unsigned_int
+void unsigned_char_shl_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4300
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_signed_int
+void unsigned_char_shl_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4400
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_unsigned_char
+void signed_char_shl_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4500
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char
+void signed_char_shl_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4600
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char_unsigned_int
+void signed_char_shl_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4700
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char_signed_int
+void signed_char_shl_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4800
+ (*LHS) <<= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound right-shift operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_unsigned_char
+void unsigned_char_shr_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4900
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_signed_char
+void unsigned_char_shr_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5000
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_unsigned_int
+void unsigned_char_shr_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5100
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_signed_int
+void unsigned_char_shr_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5200
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_unsigned_char
+void signed_char_shr_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5300
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char
+void signed_char_shr_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5400
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char_unsigned_int
+void signed_char_shr_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5500
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char_signed_int
+void signed_char_shr_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5600
+ (*LHS) >>= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound and operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_unsigned_char
+void unsigned_char_and_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5700
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_signed_char
+void unsigned_char_and_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5800
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_unsigned_int
+void unsigned_char_and_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5900_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5900_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5900
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_signed_int
+void unsigned_char_and_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6000
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_unsigned_char
+void signed_char_and_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6100
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char
+void signed_char_and_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6200
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char_unsigned_int
+void signed_char_and_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6300
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char_signed_int
+void signed_char_and_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6400
+ (*LHS) &= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound xor operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_unsigned_char
+void unsigned_char_or_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6500
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_signed_char
+void unsigned_char_or_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6600
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_unsigned_int
+void unsigned_char_or_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6700_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6700_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6700
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_signed_int
+void unsigned_char_or_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6800
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_unsigned_char
+void signed_char_or_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6900
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char
+void signed_char_or_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7000
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char_unsigned_int
+void signed_char_or_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7100
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char_signed_int
+void signed_char_or_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7200
+ (*LHS) |= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound or operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_unsigned_char
+void unsigned_char_xor_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7300
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_signed_char
+void unsigned_char_xor_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7400
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_unsigned_int
+void unsigned_char_xor_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7500
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_signed_int
+void unsigned_char_xor_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7600
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_unsigned_char
+void signed_char_xor_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7700
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char
+void signed_char_xor_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7800
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char_unsigned_int
+void signed_char_xor_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7900
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char_signed_int
+void signed_char_xor_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_8000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_8000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 8000
+ (*LHS) ^= RHS;
+}
diff --git a/test/CodeGen/catch-implicit-integer-truncations-basics-negatives.c b/test/CodeGen/catch-implicit-integer-truncations-basics-negatives.c
index d5554b98d4..1b543a3a7f 100644
--- a/test/CodeGen/catch-implicit-integer-truncations-basics-negatives.c
+++ b/test/CodeGen/catch-implicit-integer-truncations-basics-negatives.c
@@ -1,7 +1,9 @@
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
-// CHECK-DAG: @[[LINE_100_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_300_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}, {{.*}}, i8 0 }
+// CHECK-DAG: @[[LINE_100_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+// CHECK-DAG: @[[LINE_200_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+// CHECK-DAG: @[[LINE_300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}, {{.*}}, i8 2 }
//----------------------------------------------------------------------------//
// Unsigned case.
@@ -10,7 +12,7 @@
// CHECK-LABEL: @blacklist_0_convert_unsigned_int_to_unsigned_char
__attribute__((no_sanitize("undefined"))) unsigned char blacklist_0_convert_unsigned_int_to_unsigned_char(unsigned int x) {
// We are not in "undefined" group, so that doesn't work.
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_UNSIGNED_TRUNCATION]] to i8*)
#line 100
return x;
}
@@ -30,6 +32,19 @@ __attribute__((no_sanitize("implicit-integer-truncation"))) unsigned char blackl
return x;
}
+// CHECK-LABEL: @blacklist_4_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("implicit-unsigned-integer-truncation"))) unsigned char blacklist_4_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_5_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("implicit-signed-integer-truncation"))) unsigned char blacklist_5_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ // This is an unsigned truncation, not signed-one.
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_UNSIGNED_TRUNCATION]] to i8*)
+#line 200
+ return x;
+}
+
//----------------------------------------------------------------------------//
// Signed case.
//----------------------------------------------------------------------------//
@@ -37,7 +52,7 @@ __attribute__((no_sanitize("implicit-integer-truncation"))) unsigned char blackl
// CHECK-LABEL: @blacklist_0_convert_signed_int_to_signed_char
__attribute__((no_sanitize("undefined"))) signed char blacklist_0_convert_signed_int_to_signed_char(signed int x) {
// We are not in "undefined" group, so that doesn't work.
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGNED_TRUNCATION]] to i8*)
#line 300
return x;
}
@@ -56,3 +71,16 @@ __attribute__((no_sanitize("implicit-conversion"))) signed char blacklist_2_conv
__attribute__((no_sanitize("implicit-integer-truncation"))) signed char blacklist_3_convert_signed_int_to_signed_char(signed int x) {
return x;
}
+
+// CHECK-LABEL: @blacklist_4_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("implicit-signed-integer-truncation"))) signed char blacklist_4_convert_signed_int_to_signed_char(signed int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_5_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("implicit-unsigned-integer-truncation"))) signed char blacklist_5_convert_signed_int_to_signed_char(signed int x) {
+ // This is an signed truncation, not unsigned-one.
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*)
+#line 400
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-integer-truncations-basics.c b/test/CodeGen/catch-implicit-integer-truncations-basics.c
index 987f54c551..1a34246d78 100644
--- a/test/CodeGen/catch-implicit-integer-truncations-basics.c
+++ b/test/CodeGen/catch-implicit-integer-truncations-basics.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
// Test plan:
// * Two types - int and char
@@ -9,10 +9,10 @@
// However, not all of them should result in the check.
// So here, we *only* check which should and which should not result in checks.
-// CHECK-DAG: @[[LINE_500_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_1100_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_1500_TRUNCATION:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 0 }
-// CHECK-DAG: @[[LINE_1600_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 0 }
+// CHECK-DAG: @[[LINE_500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+// CHECK-DAG: @[[LINE_1100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 2 }
// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
@@ -40,7 +40,7 @@ signed char convert_signed_char_to_signed_char(signed char x) {
// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*)
#line 500
return x;
}
@@ -77,7 +77,7 @@ unsigned int convert_signed_int_to_unsigned_int(signed int x) {
// CHECK-LABEL: @convert_signed_int_to_unsigned_char
unsigned char convert_signed_int_to_unsigned_char(signed int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGNED_TRUNCATION]] to i8*)
#line 1100
return x;
}
@@ -102,14 +102,14 @@ unsigned int convert_signed_char_to_unsigned_int(signed char x) {
// CHECK-LABEL: @convert_unsigned_int_to_signed_char
signed char convert_unsigned_int_to_signed_char(unsigned int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION]] to i8*)
#line 1500
return x;
}
// CHECK-LABEL: @convert_signed_int_to_signed_char
signed char convert_signed_int_to_signed_char(signed int x) {
- // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_TRUNCATION]] to i8*)
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*)
#line 1600
return x;
}
diff --git a/test/CodeGen/catch-implicit-integer-truncations.c b/test/CodeGen/catch-implicit-integer-truncations.c
index ea5b476c22..bcc9273439 100644
--- a/test/CodeGen/catch-implicit-integer-truncations.c
+++ b/test/CodeGen/catch-implicit-integer-truncations.c
@@ -1,21 +1,21 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-trap=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
-// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 }
// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_INT:.*]] = {{.*}} c"'int'\00" }
-// CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
-// CHECK-SANITIZE-ANYRECOVER: @[[LINE_300_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 0 }
-// CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
// CHECK-SANITIZE-ANYRECOVER: @[[UINT32:.*]] = {{.*}} c"'uint32_t' (aka 'unsigned int')\00" }
// CHECK-SANITIZE-ANYRECOVER: @[[UINT8:.*]] = {{.*}} c"'uint8_t' (aka 'unsigned char')\00" }
-// CHECK-SANITIZE-ANYRECOVER: @[[LINE_500_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[UINT32]], {{.*}}* @[[UINT8]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[UINT32]], {{.*}}* @[[UINT8]], i8 1 }
// ========================================================================== //
// The expected true-positives. These are implicit conversions, and they truncate.
@@ -30,8 +30,8 @@ unsigned char unsigned_int_to_unsigned_char(unsigned int src) {
// CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
- // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
- // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
@@ -50,8 +50,8 @@ unsigned char signed_int_to_unsigned_char(signed int src) {
// CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
- // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
- // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
@@ -70,8 +70,8 @@ signed char unsigned_int_to_signed_char(unsigned int src) {
// CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
- // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
- // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
@@ -90,8 +90,8 @@ signed char signed_int_to_signed_char(signed int src) {
// CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
- // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
- // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
@@ -117,8 +117,8 @@ uint8_t uint32_to_uint8(uint32_t src) {
// CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
// CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
- // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
- // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
diff --git a/test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change-CompoundAssignOperator.c b/test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change-CompoundAssignOperator.c
new file mode 100644
index 0000000000..3dfa79fc82
--- /dev/null
+++ b/test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change-CompoundAssignOperator.c
@@ -0,0 +1,2553 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-trap=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+
+// LHS can be of 2 types: unsigned char and signed char
+// RHS can be of 4 types: unsigned char, signed char, unsigned int, signed int.
+// Therefore there are total of 8 tests per group.
+
+// Also there are total of 10 compound operators (+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=)
+
+// CHECK-SANITIZE-ANYRECOVER: @[[INT:.*]] = {{.*}} c"'int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_700_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_1800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2300_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 2300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_2900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 2900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3100_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 3100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 3800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_3900_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 3900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_4900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 4900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_5800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 5800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6100, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6300_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 6300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6500, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_6900_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 6900, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7100_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 7100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7200, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7300, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7400, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7600, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7700_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7700, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7800_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 7800, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_7900_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 7900, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_8000_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 8000, i32 10 }, {{.*}}* @[[INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+//----------------------------------------------------------------------------//
+// Compound add operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_unsigned_char
+void unsigned_char_add_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 100
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_signed_char
+void unsigned_char_add_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 200
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_unsigned_int
+void unsigned_char_add_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 300
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_add_signed_char_signed_int
+void unsigned_char_add_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 400
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_unsigned_char
+void signed_char_add_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 500
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char
+void signed_char_add_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 600
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char_unsigned_int
+void signed_char_add_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 700
+ (*LHS) += RHS;
+}
+
+// CHECK-LABEL: @signed_char_add_signed_char_signed_int
+void signed_char_add_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = add nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 800
+ (*LHS) += RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound subtract operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_unsigned_char
+void unsigned_char_sub_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 900
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_signed_char
+void unsigned_char_sub_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1000
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_unsigned_int
+void unsigned_char_sub_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 1100
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_sub_signed_char_signed_int
+void unsigned_char_sub_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1200
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_unsigned_char
+void signed_char_sub_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1300
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char
+void signed_char_sub_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1400
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char_unsigned_int
+void signed_char_sub_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1500
+ (*LHS) -= RHS;
+}
+
+// CHECK-LABEL: @signed_char_sub_signed_char_signed_int
+void signed_char_sub_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sub nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1600
+ (*LHS) -= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound multiply operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_unsigned_char
+void unsigned_char_mul_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1700
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_signed_char
+void unsigned_char_mul_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 1800
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_unsigned_int
+void unsigned_char_mul_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 1900
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_mul_signed_char_signed_int
+void unsigned_char_mul_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2000
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_unsigned_char
+void signed_char_mul_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2100
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char
+void signed_char_mul_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2200
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char_unsigned_int
+void signed_char_mul_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2300_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2300_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2300
+ (*LHS) *= RHS;
+}
+
+// CHECK-LABEL: @signed_char_mul_signed_char_signed_int
+void signed_char_mul_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = mul nsw i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2400
+ (*LHS) *= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound divide operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_unsigned_char
+void unsigned_char_div_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2500
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_signed_char
+void unsigned_char_div_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2600
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_unsigned_int
+void unsigned_char_div_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 2700
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_div_signed_char_signed_int
+void unsigned_char_div_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2800
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_unsigned_char
+void signed_char_div_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_2900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 2900
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char
+void signed_char_div_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3000
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char_unsigned_int
+void signed_char_div_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = udiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3100
+ (*LHS) /= RHS;
+}
+
+// CHECK-LABEL: @signed_char_div_signed_char_signed_int
+void signed_char_div_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = sdiv i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3200
+ (*LHS) /= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound remainder operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_unsigned_char
+void unsigned_char_rem_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3300
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_signed_char
+void unsigned_char_rem_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3400
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_unsigned_int
+void unsigned_char_rem_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 3500
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_rem_signed_char_signed_int
+void unsigned_char_rem_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3600
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_unsigned_char
+void signed_char_rem_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3700
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char
+void signed_char_rem_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3800
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char_unsigned_int
+void signed_char_rem_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = urem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3900_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_3900_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 3900
+ (*LHS) %= RHS;
+}
+
+// CHECK-LABEL: @signed_char_rem_signed_char_signed_int
+void signed_char_rem_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = srem i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4000
+ (*LHS) %= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound left-shift operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_unsigned_char
+void unsigned_char_shl_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4100
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_signed_char
+void unsigned_char_shl_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4200
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_unsigned_int
+void unsigned_char_shl_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4300
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shl_signed_char_signed_int
+void unsigned_char_shl_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4400
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_unsigned_char
+void signed_char_shl_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4500
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char
+void signed_char_shl_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4600
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char_unsigned_int
+void signed_char_shl_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4700
+ (*LHS) <<= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shl_signed_char_signed_int
+void signed_char_shl_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = shl i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4800
+ (*LHS) <<= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound right-shift operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_unsigned_char
+void unsigned_char_shr_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_4900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 4900
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_signed_char
+void unsigned_char_shr_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5000
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_unsigned_int
+void unsigned_char_shr_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5100
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_shr_signed_char_signed_int
+void unsigned_char_shr_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5200
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_unsigned_char
+void signed_char_shr_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5300
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char
+void signed_char_shr_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5400
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char_unsigned_int
+void signed_char_shr_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5500
+ (*LHS) >>= RHS;
+}
+
+// CHECK-LABEL: @signed_char_shr_signed_char_signed_int
+void signed_char_shr_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = ashr i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5600
+ (*LHS) >>= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound and operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_unsigned_char
+void unsigned_char_and_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5700
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_signed_char
+void unsigned_char_and_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_5800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 5800
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_unsigned_int
+void unsigned_char_and_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 5900
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_and_signed_char_signed_int
+void unsigned_char_and_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6000
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_unsigned_char
+void signed_char_and_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6100_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6100
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char
+void signed_char_and_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6200
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char_unsigned_int
+void signed_char_and_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6300_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6300_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6300
+ (*LHS) &= RHS;
+}
+
+// CHECK-LABEL: @signed_char_and_signed_char_signed_int
+void signed_char_and_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = and i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6400
+ (*LHS) &= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound xor operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_unsigned_char
+void unsigned_char_or_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6500_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6500
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_signed_char
+void unsigned_char_or_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6600
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_unsigned_int
+void unsigned_char_or_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 6700
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_or_signed_char_signed_int
+void unsigned_char_or_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6800
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_unsigned_char
+void signed_char_or_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_6900_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 6900
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char
+void signed_char_or_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7000
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char_unsigned_int
+void signed_char_or_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7100
+ (*LHS) |= RHS;
+}
+
+// CHECK-LABEL: @signed_char_or_signed_char_signed_int
+void signed_char_or_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = or i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7200
+ (*LHS) |= RHS;
+}
+
+//----------------------------------------------------------------------------//
+// Compound or operator. //
+//----------------------------------------------------------------------------//
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_unsigned_char
+void unsigned_char_xor_signed_char_unsigned_char(unsigned char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7300
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_signed_char
+void unsigned_char_xor_signed_char_signed_char(unsigned char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7400
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_unsigned_int
+void unsigned_char_xor_signed_char_unsigned_int(unsigned char *LHS, unsigned int RHS) {
+#line 7500
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @unsigned_char_xor_signed_char_signed_int
+void unsigned_char_xor_signed_char_signed_int(unsigned char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = zext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7600_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7600
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_unsigned_char
+void signed_char_xor_unsigned_char(signed char *LHS, unsigned char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = zext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7700_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7700
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char
+void signed_char_xor_signed_char(signed char *LHS, signed char RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i8, align 1
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i8 %[[ARG1:.*]], i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHS:.*]] = load i8, i8* %[[RHSADDR]], align 1
+ // CHECK-NEXT: %[[RHSEXT:.*]] = sext i8 %[[RHS]] to i32
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHSEXT]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7800_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7800
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char_unsigned_int
+void signed_char_xor_signed_char_unsigned_int(signed char *LHS, unsigned int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7900_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_7900_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 7900
+ (*LHS) ^= RHS;
+}
+
+// CHECK-LABEL: @signed_char_xor_signed_char_signed_int
+void signed_char_xor_signed_char_signed_int(signed char *LHS, signed int RHS) {
+ // CHECK: {
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: %[[ADDRESS:.*]] = alloca i8*, align 8
+ // CHECK-NEXT: %[[RHSADDR:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i8* %[[ARG0:.*]], i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: store i32 %[[ARG1:.*]], i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[RHS:.*]] = load i32, i32* %[[RHSADDR]], align 4
+ // CHECK-NEXT: %[[LHSADDR:.*]] = load i8*, i8** %[[ADDRESS]], align 8
+ // CHECK-NEXT: %[[LHS:.*]] = load i8, i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: %[[LHSEXT:.*]] = sext i8 %[[LHS]] to i32
+ // CHECK-NEXT: %[[SRC:.*]] = xor i32 %[[LHSEXT]], %[[RHS]]
+ // CHECK-NEXT: %[[DST:.*]] = trunc i32 %[[SRC]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_8000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_8000_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: store i8 %[[DST]], i8* %[[LHSADDR]], align 1
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+#line 8000
+ (*LHS) ^= RHS;
+}
diff --git a/test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change.c b/test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change.c
new file mode 100644
index 0000000000..45171baeba
--- /dev/null
+++ b/test/CodeGen/catch-implicit-signed-integer-truncation-or-sign-change.c
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-trap=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_100_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 4 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_200_SIGN_CHANGE:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_300_SIGN_CHANGE:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 }
+// CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 }
+
+//============================================================================//
+// Both sanitizers are enabled, and not disabled per-function.
+//============================================================================//
+
+// CHECK-LABEL: @unsigned_int_to_signed_char
+// CHECK-SAME: (i32 %[[SRC:.*]])
+signed char unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-NEXT: [[ENTRY:.*]]:
+ // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[CONV]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[DST]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 100
+ return src;
+}
+
+//============================================================================//
+// Truncation sanitizer is disabled per-function.
+//============================================================================//
+
+// CHECK-LABEL: @unsigned_int_to_signed_char__no_truncation_sanitizer
+// CHECK-SAME: (i32 %[[SRC:.*]])
+__attribute__((no_sanitize("implicit-integer-truncation"))) signed char
+unsigned_int_to_signed_char__no_truncation_sanitizer(unsigned int src) {
+ // CHECK-NEXT: [[ENTRY:.*]]:
+ // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 200
+ return src;
+}
+
+//============================================================================//
+// Signed truncation sanitizer is disabled per-function.
+//============================================================================//
+
+// CHECK-LABEL: @unsigned_int_to_signed_char__no_signed_truncation_sanitizer
+// CHECK-SAME: (i32 %[[SRC:.*]])
+__attribute__((no_sanitize("implicit-signed-integer-truncation"))) signed char
+unsigned_int_to_signed_char__no_signed_truncation_sanitizer(unsigned int src) {
+ // CHECK-NEXT: [[ENTRY:.*]]:
+ // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGN_CHANGE]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 300
+ return src;
+}
+
+//============================================================================//
+// Sign change sanitizer is disabled per-function
+//============================================================================//
+
+// CHECK-LABEL: @unsigned_int_to_signed_char__no_sign_change_sanitizer
+// CHECK-SAME: (i32 %[[SRC:.*]])
+__attribute__((no_sanitize("implicit-integer-sign-change"))) signed char
+unsigned_int_to_signed_char__no_sign_change_sanitizer(unsigned int src) {
+ // CHECK-NEXT: [[ENTRY:.*]]:
+ // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[CONV]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[DST]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+#line 400
+ return src;
+}
+
+//============================================================================//
+// Both sanitizers are disabled per-function.
+//============================================================================//
+
+// CHECK-LABEL: @unsigned_int_to_signed_char__no_sanitizers
+// CHECK-SAME: (i32 %[[SRC:.*]])
+__attribute__((no_sanitize("implicit-integer-truncation"),
+ no_sanitize("implicit-integer-sign-change"))) signed char
+unsigned_int_to_signed_char__no_sanitizers(unsigned int src) {
+ // CHECK-NEXT: [[ENTRY:.*]]:
+ // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
+ // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]]
+ // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
+ // CHECK-NEXT: ret i8 %[[CONV]]
+ // CHECK-NEXT: }
+ return src;
+}
diff --git a/test/CodeGen/catch-implicit-signed-integer-truncations-basics-negatives.c b/test/CodeGen/catch-implicit-signed-integer-truncations-basics-negatives.c
new file mode 100644
index 0000000000..4ec4385c9f
--- /dev/null
+++ b/test/CodeGen/catch-implicit-signed-integer-truncations-basics-negatives.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation -fsanitize-recover=implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// CHECK-DAG: @[[LINE_100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+
+// CHECK-LABEL: @blacklist_0_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("undefined"))) signed char blacklist_0_convert_signed_int_to_signed_char(signed int x) {
+ // We are not in "undefined" group, so that doesn't work.
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_SIGNED_TRUNCATION]] to i8*)
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_1_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("integer"))) signed char blacklist_1_convert_signed_int_to_signed_char(signed int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_2_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("implicit-conversion"))) signed char blacklist_2_convert_signed_int_to_signed_char(signed int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_3_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("implicit-integer-truncation"))) signed char blacklist_3_convert_signed_int_to_signed_char(signed int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_4_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("implicit-signed-integer-truncation"))) signed char blacklist_4_convert_signed_int_to_signed_char(signed int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_5_convert_signed_int_to_signed_char
+__attribute__((no_sanitize("implicit-unsigned-integer-truncation"))) signed char blacklist_5_convert_signed_int_to_signed_char(signed int x) {
+ // This is an signed truncation, not unsigned-one.
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*)
+#line 200
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-signed-integer-truncations-basics.c b/test/CodeGen/catch-implicit-signed-integer-truncations-basics.c
new file mode 100644
index 0000000000..a0fa2c3a22
--- /dev/null
+++ b/test/CodeGen/catch-implicit-signed-integer-truncations-basics.c
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation -fsanitize-recover=implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// Test plan:
+// * Two types - int and char
+// * Two signs - signed and unsigned
+// * Square that - we have input and output types.
+// Thus, there are total of (2*2)^2 == 16 tests.
+// These are all the possible variations/combinations of casts.
+// However, not all of them should result in the check.
+// So here, we *only* check which should and which should not result in checks.
+
+// CHECK-DAG: @[[LINE_1100_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1500_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+// CHECK-DAG: @[[LINE_1600_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 2 }
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
+unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_char
+unsigned char convert_unsigned_char_to_unsigned_char(unsigned char x) {
+#line 200
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_int
+signed int convert_signed_int_to_signed_int(signed int x) {
+#line 300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_char
+signed char convert_signed_char_to_signed_char(signed char x) {
+#line 400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
+unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
+#line 500
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_int
+unsigned int convert_unsigned_char_to_unsigned_int(unsigned char x) {
+#line 600
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_int
+signed int convert_unsigned_char_to_signed_int(unsigned char x) {
+#line 700
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_int
+signed int convert_signed_char_to_signed_int(signed char x) {
+#line 800
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_int
+signed int convert_unsigned_int_to_signed_int(unsigned int x) {
+#line 900
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_int
+unsigned int convert_signed_int_to_unsigned_int(signed int x) {
+#line 1000
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_char
+unsigned char convert_signed_int_to_unsigned_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGNED_TRUNCATION]] to i8*)
+#line 1100
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_char
+unsigned char convert_signed_char_to_unsigned_char(signed char x) {
+#line 1200
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_char
+signed char convert_unsigned_char_to_signed_char(unsigned char x) {
+#line 1300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_int
+unsigned int convert_signed_char_to_unsigned_int(signed char x) {
+#line 1400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_char
+signed char convert_unsigned_int_to_signed_char(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGNED_TRUNCATION]] to i8*)
+#line 1500
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_char
+signed char convert_signed_int_to_signed_char(signed int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGNED_TRUNCATION]] to i8*)
+#line 1600
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-unsigned-integer-truncations-basics-negatives.c b/test/CodeGen/catch-implicit-unsigned-integer-truncations-basics-negatives.c
new file mode 100644
index 0000000000..de6c098396
--- /dev/null
+++ b/test/CodeGen/catch-implicit-unsigned-integer-truncations-basics-negatives.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// CHECK-DAG: @[[LINE_100_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+// CHECK-DAG: @[[LINE_200_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+
+// CHECK-LABEL: @blacklist_0_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("undefined"))) unsigned char blacklist_0_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ // We are not in "undefined" group, so that doesn't work.
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_UNSIGNED_TRUNCATION]] to i8*)
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_1_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("integer"))) unsigned char blacklist_1_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_2_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("implicit-conversion"))) unsigned char blacklist_2_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_3_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("implicit-integer-truncation"))) unsigned char blacklist_3_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_4_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("implicit-unsigned-integer-truncation"))) unsigned char blacklist_4_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ return x;
+}
+
+// CHECK-LABEL: @blacklist_5_convert_unsigned_int_to_unsigned_char
+__attribute__((no_sanitize("implicit-signed-integer-truncation"))) unsigned char blacklist_5_convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ // This is an unsigned truncation, not signed-one.
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_UNSIGNED_TRUNCATION]] to i8*)
+#line 200
+ return x;
+}
diff --git a/test/CodeGen/catch-implicit-unsigned-integer-truncations-basics.c b/test/CodeGen/catch-implicit-unsigned-integer-truncations-basics.c
new file mode 100644
index 0000000000..7eb0f0f8c9
--- /dev/null
+++ b/test/CodeGen/catch-implicit-unsigned-integer-truncations-basics.c
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK
+
+// Test plan:
+// * Two types - int and char
+// * Two signs - signed and unsigned
+// * Square that - we have input and output types.
+// Thus, there are total of (2*2)^2 == 16 tests.
+// These are all the possible variations/combinations of casts.
+// However, not all of them should result in the check.
+// So here, we *only* check which should and which should not result in checks.
+
+// CHECK-DAG: @[[LINE_500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}, {{.*}}, i8 1 }
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
+unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
+#line 100
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_char
+unsigned char convert_unsigned_char_to_unsigned_char(unsigned char x) {
+#line 200
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_int
+signed int convert_signed_int_to_signed_int(signed int x) {
+#line 300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_char
+signed char convert_signed_char_to_signed_char(signed char x) {
+#line 400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
+unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
+ // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*)
+#line 500
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_unsigned_int
+unsigned int convert_unsigned_char_to_unsigned_int(unsigned char x) {
+#line 600
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_int
+signed int convert_unsigned_char_to_signed_int(unsigned char x) {
+#line 700
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_signed_int
+signed int convert_signed_char_to_signed_int(signed char x) {
+#line 800
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_int
+signed int convert_unsigned_int_to_signed_int(unsigned int x) {
+#line 900
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_int
+unsigned int convert_signed_int_to_unsigned_int(signed int x) {
+#line 1000
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_unsigned_char
+unsigned char convert_signed_int_to_unsigned_char(signed int x) {
+#line 1100
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_char
+unsigned char convert_signed_char_to_unsigned_char(signed char x) {
+#line 1200
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_char_to_signed_char
+signed char convert_unsigned_char_to_signed_char(unsigned char x) {
+#line 1300
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_char_to_unsigned_int
+unsigned int convert_signed_char_to_unsigned_int(signed char x) {
+#line 1400
+ return x;
+}
+
+// CHECK-LABEL: @convert_unsigned_int_to_signed_char
+signed char convert_unsigned_int_to_signed_char(unsigned int x) {
+#line 1500
+ return x;
+}
+
+// CHECK-LABEL: @convert_signed_int_to_signed_char
+signed char convert_signed_int_to_signed_char(signed int x) {
+#line 1600
+ return x;
+}
diff --git a/test/CodeGen/cf-runtime-abi.c b/test/CodeGen/cf-runtime-abi.c
new file mode 100644
index 0000000000..d4089771a6
--- /dev/null
+++ b/test/CodeGen/cf-runtime-abi.c
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC-LLP64
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fcf-runtime-abi=objc -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fcf-runtime-abi=objc -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC-LLP64
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcf-runtime-abi=objc -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fcf-runtime-abi=standalone -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fcf-runtime-abi=standalone -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC-LLP64
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcf-runtime-abi=standalone -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-OBJC
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fcf-runtime-abi=swift -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-64
+// RUN: %clang_cc1 -triple aarch64-apple-ios -fcf-runtime-abi=swift -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-64
+// RUN: %clang_cc1 -triple armv7k-apple-watchos -fcf-runtime-abi=swift -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-32
+// RUN: %clang_cc1 -triple armv7-apple-tvos -fcf-runtime-abi=swift -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-32
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fcf-runtime-abi=swift -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-5_0-64
+// RUN: %clang_cc1 -triple armv7-unknown-linux-android -fcf-runtime-abi=swift -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-5_0-32
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fcf-runtime-abi=swift-5.0 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-64
+// RUN: %clang_cc1 -triple aarch64-apple-ios -fcf-runtime-abi=swift-5.0 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-64
+// RUN: %clang_cc1 -triple armv7k-apple-watchos -fcf-runtime-abi=swift-5.0 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-32
+// RUN: %clang_cc1 -triple armv7-apple-tvos -fcf-runtime-abi=swift-5.0 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-5_0-32
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fcf-runtime-abi=swift-5.0 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-5_0-64
+// RUN: %clang_cc1 -triple armv7-unknown-linux-android -fcf-runtime-abi=swift-5.0 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-5_0-32
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fcf-runtime-abi=swift-4.2 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_2-64
+// RUN: %clang_cc1 -triple aarch64-apple-ios -fcf-runtime-abi=swift-4.2 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_2-64
+// RUN: %clang_cc1 -triple armv7k-apple-watchos -fcf-runtime-abi=swift-4.2 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_2-32
+// RUN: %clang_cc1 -triple armv7-apple-tvos -fcf-runtime-abi=swift-4.2 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_2-32
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fcf-runtime-abi=swift-4.2 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-4_2-64
+// RUN: %clang_cc1 -triple armv7-unknown-linux-android -fcf-runtime-abi=swift-4.2 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-4_2-32
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fcf-runtime-abi=swift-4.1 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_1-64
+// RUN: %clang_cc1 -triple aarch64-apple-ios -fcf-runtime-abi=swift-4.1 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_1-64
+// RUN: %clang_cc1 -triple armv7k-apple-watchos -fcf-runtime-abi=swift-4.1 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_1-32
+// RUN: %clang_cc1 -triple armv7-apple-tvos -fcf-runtime-abi=swift-4.1 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-DARWIN-4_1-32
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fcf-runtime-abi=swift-4.1 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-4_1-64
+// RUN: %clang_cc1 -triple armv7-unknown-linux-android -fcf-runtime-abi=swift-4.1 -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-SWIFT-4_1-32
+
+const __NSConstantString *s = __builtin___CFStringMakeConstantString("");
+
+// CHECK-OBJC: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i64 0 }
+// CHECK-OBJC-LLP64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+
+// CHECK-SWIFT-DARWIN-5_0-64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i64 ptrtoint (i64* @"$s15SwiftFoundation19_NSCFConstantStringCN" to i64), i64 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i64 0 }
+// CHECK-SWIFT-DARWIN-5_0-32: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32 ptrtoint (i32* @"$s15SwiftFoundation19_NSCFConstantStringCN" to i32), i32 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-5_0-64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i64 ptrtoint (i64* @"$s10Foundation19_NSCFConstantStringCN" to i64), i64 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i64 0 }
+// CHECK-SWIFT-5_0-32: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32 ptrtoint (i32* @"$s10Foundation19_NSCFConstantStringCN" to i32), i32 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+
+// CHECK-SWIFT-DARWIN-4_2-64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i64 ptrtoint (i64* @"$S15SwiftFoundation19_NSCFConstantStringCN" to i64), i64 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-DARWIN-4_2-32: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32 ptrtoint (i32* @"$S15SwiftFoundation19_NSCFConstantStringCN" to i32), i32 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-4_2-64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i64 ptrtoint (i64* @"$S10Foundation19_NSCFConstantStringCN" to i64), i64 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-4_2-32: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32 ptrtoint (i32* @"$S10Foundation19_NSCFConstantStringCN" to i32), i32 1, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+
+// CHECK-SWIFT-DARWIN-4_1-64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i64 ptrtoint (i64* @__T015SwiftFoundation19_NSCFConstantStringCN to i64), i64 5, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-DARWIN-4_1-32: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32 ptrtoint (i32* @__T015SwiftFoundation19_NSCFConstantStringCN to i32), i32 5, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-4_1-64: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i64 ptrtoint (i64* @__T010Foundation19_NSCFConstantStringCN to i64), i64 5, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+// CHECK-SWIFT-4_1-32: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32 ptrtoint (i32* @__T010Foundation19_NSCFConstantStringCN to i32), i32 5, i64 1992, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i32 0 }
+
diff --git a/test/CodeGen/code-coverage-filter.c b/test/CodeGen/code-coverage-filter.c
new file mode 100644
index 0000000000..5186dadcd8
--- /dev/null
+++ b/test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang -S -emit-llvm --coverage %s -o %t
+// RUN: FileCheck -check-prefix=ALL < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER2 < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=JUST-C < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=NONE < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=JUST-C < %t %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+ test1();
+ test2();
+}
+
+// ALL: void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
diff --git a/test/CodeGen/codemodels.c b/test/CodeGen/codemodels.c
index 30fdb25933..cc68bf2120 100644
--- a/test/CodeGen/codemodels.c
+++ b/test/CodeGen/codemodels.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NOMODEL
-// RUN: %clang_cc1 -emit-llvm -mcode-model tiny %s -o - | FileCheck %s -check-prefix=CHECK-TINY
+// RUN: %clang_cc1 -triple aarch64-unknown-none-eabi -emit-llvm -mcode-model tiny %s -o - | FileCheck %s -check-prefix=CHECK-TINY
// RUN: %clang_cc1 -emit-llvm -mcode-model small %s -o - | FileCheck %s -check-prefix=CHECK-SMALL
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -mcode-model kernel %s -o - | FileCheck %s -check-prefix=CHECK-KERNEL
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -mcode-model medium %s -o - | FileCheck %s -check-prefix=CHECK-MEDIUM
diff --git a/test/CodeGen/debug-info-abspath.c b/test/CodeGen/debug-info-abspath.c
new file mode 100644
index 0000000000..b20ed317d7
--- /dev/null
+++ b/test/CodeGen/debug-info-abspath.c
@@ -0,0 +1,34 @@
+// RUN: mkdir -p %t/UNIQUEISH_SENTINEL
+// RUN: cp %s %t/UNIQUEISH_SENTINEL/debug-info-abspath.c
+
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
+// RUN: %t/UNIQUEISH_SENTINEL/debug-info-abspath.c -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// RUN: cp %s %t.c
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
+// RUN: %t.c -emit-llvm -o - | FileCheck %s --check-prefix=INTREE
+
+// RUN: cd %t/UNIQUEISH_SENTINEL
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
+// RUN: debug-info-abspath.c -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=CURDIR
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
+// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefix=CURDIR
+
+void foo() {}
+
+// Since %s is an absolute path, directory should be the common
+// prefix, but the directory part should be part of the filename.
+
+// CHECK: = distinct !DISubprogram({{.*}}file: ![[SPFILE:[0-9]+]]
+// CHECK: ![[SPFILE]] = !DIFile(filename: "{{.*}}UNIQUEISH_SENTINEL
+// CHECK-SAME: debug-info-abspath.c"
+// CHECK-NOT: directory: "{{.*}}UNIQUEISH_SENTINEL
+
+// INTREE: = distinct !DISubprogram({{.*}}![[SPFILE:[0-9]+]]
+// INTREE: DIFile({{.*}}directory: "{{.+}}CodeGen{{.*}}")
+
+// CURDIR: = distinct !DICompileUnit({{.*}}file: ![[CUFILE:[0-9]+]]
+// CURDIR: ![[CUFILE]] = !DIFile({{.*}}directory: "{{.+}}UNIQUEISH_SENTINEL")
+
diff --git a/test/CodeGen/debug-info-compilation-dir.c b/test/CodeGen/debug-info-compilation-dir.c
index be2cc3542d..786d23556d 100644
--- a/test/CodeGen/debug-info-compilation-dir.c
+++ b/test/CodeGen/debug-info-compilation-dir.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -fdebug-compilation-dir /nonsense -emit-llvm -debug-info-kind=limited %s -o - | FileCheck -check-prefix=CHECK-NONSENSE %s
+// RUN: mkdir -p %t.dir && cd %t.dir
+// RUN: cp %s rel.c
+// RUN: %clang_cc1 -fdebug-compilation-dir /nonsense -emit-llvm -debug-info-kind=limited rel.c -o - | FileCheck -check-prefix=CHECK-NONSENSE %s
// CHECK-NONSENSE: nonsense
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck -check-prefix=CHECK-DIR %s
diff --git a/test/CodeGen/debug-info-ranges-base-address.c b/test/CodeGen/debug-info-ranges-base-address.c
new file mode 100644
index 0000000000..dee7cc5f89
--- /dev/null
+++ b/test/CodeGen/debug-info-ranges-base-address.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck --check-prefix=NORNGBSE %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - -fdebug-ranges-base-address | FileCheck --check-prefix=RNGBSE %s
+
+// NORNGBSE-NOT: rangesBaseAddress
+// RNGBSE: !DICompileUnit({{.*}}, rangesBaseAddress: true
+
+void f1() {
+}
+
diff --git a/test/CodeGen/debug-info-scope-file.c b/test/CodeGen/debug-info-scope-file.c
index 94123bbc49..a5af595065 100644
--- a/test/CodeGen/debug-info-scope-file.c
+++ b/test/CodeGen/debug-info-scope-file.c
@@ -5,9 +5,9 @@
// CHECK: ret void, !dbg [[F1_LINE:![0-9]*]]
// CHECK: ret void, !dbg [[F2_LINE:![0-9]*]]
-// CHECK: [[F1:![0-9]*]] = distinct !DISubprogram(name: "f1",{{.*}} isDefinition: true
+// CHECK: [[F1:![0-9]*]] = distinct !DISubprogram(name: "f1",{{.*}} DISPFlagDefinition
// CHECK: [[F1_LINE]] = !DILocation({{.*}}, scope: [[F1]])
-// CHECK: [[F2:![0-9]*]] = distinct !DISubprogram(name: "f2",{{.*}} isDefinition: true
+// CHECK: [[F2:![0-9]*]] = distinct !DISubprogram(name: "f2",{{.*}} DISPFlagDefinition
// CHECK: [[F2_LINE]] = !DILocation({{.*}}, scope: [[F2]])
void f1() {
diff --git a/test/CodeGen/debug-info-vla.c b/test/CodeGen/debug-info-vla.c
index 8bd6a6d0ac..22b3930dfc 100644
--- a/test/CodeGen/debug-info-vla.c
+++ b/test/CodeGen/debug-info-vla.c
@@ -2,9 +2,9 @@
void testVLAwithSize(int s)
{
-// CHECK-DAG: dbg.declare({{.*}} %__vla_expr, metadata ![[VLAEXPR:[0-9]+]]
+// CHECK-DAG: dbg.declare({{.*}} %__vla_expr0, metadata ![[VLAEXPR:[0-9]+]]
// CHECK-DAG: dbg.declare({{.*}} %vla, metadata ![[VAR:[0-9]+]]
-// CHECK-DAG: ![[VLAEXPR]] = !DILocalVariable(name: "__vla_expr", {{.*}} flags: DIFlagArtificial
+// CHECK-DAG: ![[VLAEXPR]] = !DILocalVariable(name: "__vla_expr0", {{.*}} flags: DIFlagArtificial
// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "vla",{{.*}} line: [[@LINE+2]]
// CHECK-DAG: !DISubrange(count: ![[VLAEXPR]])
int vla[s];
diff --git a/test/CodeGen/debug-prefix-map.c b/test/CodeGen/debug-prefix-map.c
index dfb57bbe2e..f755ba47a2 100644
--- a/test/CodeGen/debug-prefix-map.c
+++ b/test/CodeGen/debug-prefix-map.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/var/empty %s -emit-llvm -o - | FileCheck %s -check-prefix CHECK-NO-MAIN-FILE-NAME
-// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/var=empty %s -emit-llvm -o - | FileCheck %s -check-prefix CHECK-EVIL
-// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/var/empty %s -emit-llvm -o - -main-file-name debug-prefix-map.c | FileCheck %s
-// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/var/empty %s -emit-llvm -o - -fdebug-compilation-dir %p | FileCheck %s -check-prefix CHECK-COMPILATION-DIR
+// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/UNLIKELY_PATH/empty %s -emit-llvm -o - | FileCheck %s -check-prefix CHECK-NO-MAIN-FILE-NAME
+// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/UNLIKELY_PATH=empty %s -emit-llvm -o - | FileCheck %s -check-prefix CHECK-EVIL
+// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/UNLIKELY_PATH/empty %s -emit-llvm -o - -main-file-name debug-prefix-map.c | FileCheck %s
+// RUN: %clang_cc1 -debug-info-kind=standalone -fdebug-prefix-map=%p=/UNLIKELY_PATH/empty %s -emit-llvm -o - -fdebug-compilation-dir %p | FileCheck %s -check-prefix CHECK-COMPILATION-DIR
#include "Inputs/stdio.h"
@@ -16,19 +16,25 @@ void test_rewrite_includes() {
vprintf("string", argp);
}
-// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/var/empty{{/|\\5C}}<stdin>"
-// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}"
-// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h"
+// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/UNLIKELY_PATH/empty{{/|\\5C}}<stdin>"
+// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/UNLIKELY_PATH/empty{{[/\\]}}{{.*}}",
+// On POSIX systems "Dir" should actually be empty, but on Windows we
+// can't recognize "/UNLIKELY_PATH" as being an absolute path.
+// CHECK-NO-MAIN-FILE-NAME-SAME: directory: "{{()|(.*:.*)}}")
+// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "/UNLIKELY_PATH/empty{{[/\\]}}Inputs/stdio.h",
+// CHECK-NO-MAIN-FILE-NAME-SAME: directory: "{{()|(.*:.*)}}")
// CHECK-NO-MAIN-FILE-NAME-NOT: !DIFile(filename:
-// CHECK-EVIL: !DIFile(filename: "/var=empty{{[/\\]}}{{.*}}"
-// CHECK-EVIL: !DIFile(filename: "/var=empty{{[/\\]}}Inputs/stdio.h"
+// CHECK-EVIL: !DIFile(filename: "/UNLIKELY_PATH=empty{{[/\\]}}{{.*}}"
+// CHECK-EVIL: !DIFile(filename: "/UNLIKELY_PATH=empty{{[/\\]}}{{.*}}Inputs/stdio.h",
+// CHECK-EVIL-SAME: directory: "{{()|(.*:.*)}}")
// CHECK-EVIL-NOT: !DIFile(filename:
-// CHECK: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}"
-// CHECK: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h"
+// CHECK: !DIFile(filename: "/UNLIKELY_PATH/empty{{[/\\]}}{{.*}}"
+// CHECK: !DIFile(filename: "/UNLIKELY_PATH/empty{{[/\\]}}{{.*}}Inputs/stdio.h",
+// CHECK-SAME: directory: "{{()|(.*:.*)}}")
// CHECK-NOT: !DIFile(filename:
-// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}", directory: "/var/empty")
-// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h", directory: "/var/empty")
+// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}", directory: "/UNLIKELY_PATH/empty")
+// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}Inputs/stdio.h", directory: "/UNLIKELY_PATH/empty")
// CHECK-COMPILATION-DIR-NOT: !DIFile(filename:
diff --git a/test/CodeGen/decl.c b/test/CodeGen/decl.c
index d62629c7fb..22c2d034ad 100644
--- a/test/CodeGen/decl.c
+++ b/test/CodeGen/decl.c
@@ -1,11 +1,11 @@
// RUN: %clang_cc1 -w -fmerge-all-constants -emit-llvm < %s | FileCheck %s
// CHECK: @test1.x = internal constant [12 x i32] [i32 1
-// CHECK: @test2.x = private unnamed_addr constant [13 x i32] [i32 1,
+// CHECK: @__const.test2.x = private unnamed_addr constant [13 x i32] [i32 1,
// CHECK: @test5w = {{(dso_local )?}}global { i32, [4 x i8] } { i32 2, [4 x i8] undef }
// CHECK: @test5y = {{(dso_local )?}}global { double } { double 7.300000e+0{{[0]*}}1 }
-// CHECK: @test6.x = private unnamed_addr constant %struct.SelectDest { i8 1, i8 2, i32 3, i32 0 }
+// CHECK: @__const.test6.x = private unnamed_addr constant %struct.SelectDest { i8 1, i8 2, i32 3, i32 0 }
// CHECK: @test7 = {{(dso_local )?}}global [2 x %struct.test7s] [%struct.test7s { i32 1, i32 2 }, %struct.test7s { i32 4, i32 0 }]
diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c
index 74532c8fa5..b29799dace 100644
--- a/test/CodeGen/designated-initializers.c
+++ b/test/CodeGen/designated-initializers.c
@@ -142,6 +142,18 @@ union_16644_t union_16644_instance_4[2] =
// CHECK: @lab = global { [4 x i8], i32 } { [4 x i8] undef, i32 123 }
struct leading_anon_bitfield { int : 32; int n; } lab = { .n = 123 };
+// rdar://45691981
+struct Base {
+ struct {
+ int A;
+ };
+};
+struct Derived {
+ struct Base B;
+};
+struct Derived D = {{}, .B.A = 42};
+// CHECK: @D = global %struct.Derived { %struct.Base { %struct.anon.4 { i32 42 } } }, align 4
+
void test1(int argc, char **argv)
{
// CHECK: internal global %struct.foo { i8* null, i32 1024 }
@@ -149,7 +161,7 @@ void test1(int argc, char **argv)
.b = 1024,
};
- // CHECK: bitcast %union.anon.4* %u2
+ // CHECK: bitcast %union.anon.5* %u2
// CHECK: call void @llvm.memset
union { int i; float f; } u2 = { };
diff --git a/test/CodeGen/dump-struct-builtin.c b/test/CodeGen/dump-struct-builtin.c
index cd85409602..929c5f7113 100644
--- a/test/CodeGen/dump-struct-builtin.c
+++ b/test/CodeGen/dump-struct-builtin.c
@@ -3,55 +3,55 @@
#include "Inputs/stdio.h"
#include <stdint.h>
-// CHECK: @unit1.a = private unnamed_addr constant %struct.U1A { i16 12 }, align 2
+// CHECK: @__const.unit1.a = private unnamed_addr constant %struct.U1A { i16 12 }, align 2
// CHECK-NEXT: [[STRUCT_STR_U1:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U1A {\0A\00"
// CHECK-NEXT: [[FIELD_U1:@[0-9]+]] = private unnamed_addr constant [11 x i8] c"short a : \00"
// CHECK-NEXT: [[FORMAT_U1:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%hd\0A\00"
// CHECK-NEXT: [[END_STRUCT_U1:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit2.a = private unnamed_addr constant %struct.U2A { i16 12 }, align 2
+// CHECK: @__const.unit2.a = private unnamed_addr constant %struct.U2A { i16 12 }, align 2
// CHECK-NEXT: [[STRUCT_STR_U2:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U2A {\0A\00"
// CHECK-NEXT: [[FIELD_U2:@[0-9]+]] = private unnamed_addr constant [20 x i8] c"unsigned short a : \00"
// CHECK-NEXT: [[FORMAT_U2:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%hu\0A\00"
// CHECK-NEXT: [[END_STRUCT_U2:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit3.a = private unnamed_addr constant %struct.U3A { i32 12 }, align 4
+// CHECK: @__const.unit3.a = private unnamed_addr constant %struct.U3A { i32 12 }, align 4
// CHECK-NEXT: [[STRUCT_STR_U3:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U3A {\0A\00"
// CHECK-NEXT: [[FIELD_U3:@[0-9]+]] = private unnamed_addr constant [9 x i8] c"int a : \00"
// CHECK-NEXT: [[FORMAT_U3:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%d\0A\00"
// CHECK-NEXT: [[END_STRUCT_U3:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit4.a = private unnamed_addr constant %struct.U4A { i32 12 }, align 4
+// CHECK: @__const.unit4.a = private unnamed_addr constant %struct.U4A { i32 12 }, align 4
// CHECK-NEXT: [[STRUCT_STR_U4:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U4A {\0A\00"
// CHECK-NEXT: [[FIELD_U4:@[0-9]+]] = private unnamed_addr constant [18 x i8] c"unsigned int a : \00"
// CHECK-NEXT: [[FORMAT_U4:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%u\0A\00"
// CHECK-NEXT: [[END_STRUCT_U4:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit5.a = private unnamed_addr constant %struct.U5A { i64 12 }, align 8
+// CHECK: @__const.unit5.a = private unnamed_addr constant %struct.U5A { i64 12 }, align 8
// CHECK-NEXT: [[STRUCT_STR_U5:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U5A {\0A\00"
// CHECK-NEXT: [[FIELD_U5:@[0-9]+]] = private unnamed_addr constant [10 x i8] c"long a : \00"
// CHECK-NEXT: [[FORMAT_U5:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%ld\0A\00"
// CHECK-NEXT: [[END_STRUCT_U5:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit6.a = private unnamed_addr constant %struct.U6A { i64 12 }, align 8
+// CHECK: @__const.unit6.a = private unnamed_addr constant %struct.U6A { i64 12 }, align 8
// CHECK-NEXT: [[STRUCT_STR_U6:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U6A {\0A\00"
// CHECK-NEXT: [[FIELD_U6:@[0-9]+]] = private unnamed_addr constant [19 x i8] c"unsigned long a : \00"
// CHECK-NEXT: [[FORMAT_U6:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%lu\0A\00"
// CHECK-NEXT: [[END_STRUCT_U6:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit7.a = private unnamed_addr constant %struct.U7A { i64 12 }, align 8
+// CHECK: @__const.unit7.a = private unnamed_addr constant %struct.U7A { i64 12 }, align 8
// CHECK-NEXT: [[STRUCT_STR_U7:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U7A {\0A\00"
// CHECK-NEXT: [[FIELD_U7:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"long long a : \00"
// CHECK-NEXT: [[FORMAT_U7:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%lld\0A\00"
// CHECK-NEXT: [[END_STRUCT_U7:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit8.a = private unnamed_addr constant %struct.U8A { i64 12 }, align 8
+// CHECK: @__const.unit8.a = private unnamed_addr constant %struct.U8A { i64 12 }, align 8
// CHECK-NEXT: [[STRUCT_STR_U8:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U8A {\0A\00"
// CHECK-NEXT: [[FIELD_U8:@[0-9]+]] = private unnamed_addr constant [24 x i8] c"unsigned long long a : \00"
// CHECK-NEXT: [[FORMAT_U8:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%llu\0A\00"
// CHECK-NEXT: [[END_STRUCT_U8:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit9.a = private unnamed_addr constant %struct.U9A { i8 97 }, align 1
+// CHECK: @__const.unit9.a = private unnamed_addr constant %struct.U9A { i8 97 }, align 1
// CHECK-NEXT: [[STRUCT_STR_U9:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U9A {\0A\00"
// CHECK-NEXT: [[FIELD_U9:@[0-9]+]] = private unnamed_addr constant [10 x i8] c"char a : \00"
// CHECK-NEXT: [[FORMAT_U9:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%c\0A\00"
@@ -59,55 +59,55 @@
// CHECK: @.str = private unnamed_addr constant [4 x i8] c"LSE\00", align 1
-// CHECK: @unit10.a = private unnamed_addr constant %struct.U10A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8
+// CHECK: @__const.unit10.a = private unnamed_addr constant %struct.U10A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8
// CHECK-NEXT: [[STRUCT_STR_U10:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U10A {\0A\00"
// CHECK-NEXT: [[FIELD_U10:@[0-9]+]] = private unnamed_addr constant [12 x i8] c"char * a : \00"
// CHECK-NEXT: [[FORMAT_U10:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00"
// CHECK-NEXT: [[END_STRUCT_U10:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit11.a = private unnamed_addr constant %struct.U11A { i8* inttoptr (i64 305419896 to i8*) }, align 8
+// CHECK: @__const.unit11.a = private unnamed_addr constant %struct.U11A { i8* inttoptr (i64 305419896 to i8*) }, align 8
// CHECK-NEXT: [[STRUCT_STR_U11:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U11A {\0A\00"
// CHECK-NEXT: [[FIELD_U11:@[0-9]+]] = private unnamed_addr constant [12 x i8] c"void * a : \00"
// CHECK-NEXT: [[FORMAT_U11:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%p\0A\00"
// CHECK-NEXT: [[END_STRUCT_U11:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit12.a = private unnamed_addr constant %struct.U12A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8
+// CHECK: @__const.unit12.a = private unnamed_addr constant %struct.U12A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8
// CHECK-NEXT: [[STRUCT_STR_U12:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U12A {\0A\00"
// CHECK-NEXT: [[FIELD_U12:@[0-9]+]] = private unnamed_addr constant [18 x i8] c"const char * a : \00"
// CHECK-NEXT: [[FORMAT_U12:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00"
// CHECK-NEXT: [[END_STRUCT_U12:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit13.a = private unnamed_addr constant %struct.U13A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8
+// CHECK: @__const.unit13.a = private unnamed_addr constant %struct.U13A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8
// CHECK-NEXT: [[STRUCT_STR_U13:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U13A {\0A\00"
// CHECK-NEXT: [[FIELD_U13:@[0-9]+]] = private unnamed_addr constant [20 x i8] c"const charstar a : \00"
// CHECK-NEXT: [[FORMAT_U13:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00"
// CHECK-NEXT: [[END_STRUCT_U13:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit14.a = private unnamed_addr constant %struct.U14A { double 0x3FF1F9ACFFA7EB6C }, align 8
+// CHECK: @__const.unit14.a = private unnamed_addr constant %struct.U14A { double 0x3FF1F9ACFFA7EB6C }, align 8
// CHECK-NEXT: [[STRUCT_STR_U14:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U14A {\0A\00"
// CHECK-NEXT: [[FIELD_U14:@[0-9]+]] = private unnamed_addr constant [12 x i8] c"double a : \00"
// CHECK-NEXT: [[FORMAT_U14:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%f\0A\00"
// CHECK-NEXT: [[END_STRUCT_U14:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit15.a = private unnamed_addr constant %struct.U15A { [3 x i32] [i32 1, i32 2, i32 3] }, align 4
+// CHECK: @__const.unit15.a = private unnamed_addr constant %struct.U15A { [3 x i32] [i32 1, i32 2, i32 3] }, align 4
// CHECK-NEXT: [[STRUCT_STR_U15:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U15A {\0A\00"
// CHECK-NEXT: [[FIELD_U15:@[0-9]+]] = private unnamed_addr constant [13 x i8] c"int [3] a : \00"
// CHECK-NEXT: [[FORMAT_U15:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%p\0A\00"
// CHECK-NEXT: [[END_STRUCT_U15:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit16.a = private unnamed_addr constant %struct.U16A { i8 12 }, align 1
+// CHECK: @__const.unit16.a = private unnamed_addr constant %struct.U16A { i8 12 }, align 1
// CHECK-NEXT: [[STRUCT_STR_U16:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U16A {\0A\00"
// CHECK-NEXT: [[FIELD_U16:@[0-9]+]] = private unnamed_addr constant [13 x i8] c"uint8_t a : \00"
// CHECK-NEXT: [[FORMAT_U16:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%hhu\0A\00"
// CHECK-NEXT: [[END_STRUCT_U16:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit17.a = private unnamed_addr constant %struct.U17A { i8 12 }, align 1
+// CHECK: @__const.unit17.a = private unnamed_addr constant %struct.U17A { i8 12 }, align 1
// CHECK-NEXT: [[STRUCT_STR_U17:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U17A {\0A\00"
// CHECK-NEXT: [[FIELD_U17:@[0-9]+]] = private unnamed_addr constant [12 x i8] c"int8_t a : \00"
// CHECK-NEXT: [[FORMAT_U17:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%hhd\0A\00"
// CHECK-NEXT: [[END_STRUCT_U17:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00"
-// CHECK: @unit18.a = private unnamed_addr constant %struct.U18A { x86_fp80 0xK3FFF8FCD67FD3F5B6000 }, align 16
+// CHECK: @__const.unit18.a = private unnamed_addr constant %struct.U18A { x86_fp80 0xK3FFF8FCD67FD3F5B6000 }, align 16
// CHECK-NEXT: [[STRUCT_STR_U18:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U18A {\0A\00"
// CHECK-NEXT: [[FIELD_U18:@[0-9]+]] = private unnamed_addr constant [17 x i8] c"long double a : \00"
// CHECK-NEXT: [[FORMAT_U18:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%Lf\0A\00"
diff --git a/test/CodeGen/dwarf-version.c b/test/CodeGen/dwarf-version.c
index cee0f031e1..39bcbc2090 100644
--- a/test/CodeGen/dwarf-version.c
+++ b/test/CodeGen/dwarf-version.c
@@ -14,14 +14,29 @@
// RUN: %clang -target powerpc-unknown-openbsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
// RUN: %clang -target powerpc-unknown-freebsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
// RUN: %clang -target i386-pc-solaris -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
-//
-// Test what -gcodeview and -gdwarf do on Windows.
-// RUN: %clang -target i686-pc-windows-msvc -gcodeview -S -emit-llvm -o - %s | FileCheck %s --check-prefix=NODWARF --check-prefix=CODEVIEW
-// RUN: %clang -target i686-pc-windows-msvc -gdwarf -gcodeview -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 --check-prefix=CODEVIEW
+
+// Check which debug info formats we use on Windows. By default, in an MSVC
+// environment, we should use codeview. You can enable dwarf, which implicitly
+// disables codeview, of you can explicitly ask for both if you don't know how
+// the app will be debugged.
+// Default is codeview.
+// RUN: %clang -target i686-pc-windows-msvc -g -S -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefixes=NODWARF,CODEVIEW
+// Explicitly request codeview.
+// RUN: %clang -target i686-pc-windows-msvc -gcodeview -S -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefixes=NODWARF,CODEVIEW
+// Explicitly request DWARF.
+// RUN: %clang -target i686-pc-windows-msvc -gdwarf -S -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefixes=VER4,NOCODEVIEW
+// Explicitly request both.
+// RUN: %clang -target i686-pc-windows-msvc -gdwarf -gcodeview -S -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefixes=VER4,CODEVIEW
int main (void) {
return 0;
}
+// NOCODEVIEW-NOT: !"CodeView"
+
// VER2: !{i32 2, !"Dwarf Version", i32 2}
// VER3: !{i32 2, !"Dwarf Version", i32 3}
// VER4: !{i32 2, !"Dwarf Version", i32 4}
@@ -29,4 +44,5 @@ int main (void) {
// NODWARF-NOT: !"Dwarf Version"
// CODEVIEW: !{i32 2, !"CodeView", i32 1}
+// NOCODEVIEW-NOT: !"CodeView"
// NODWARF-NOT: !"Dwarf Version"
diff --git a/test/CodeGen/exceptions.c b/test/CodeGen/exceptions.c
index 039ec84d2e..57b869196b 100644
--- a/test/CodeGen/exceptions.c
+++ b/test/CodeGen/exceptions.c
@@ -23,6 +23,7 @@ void test1() {
void test2_helper();
void test2() {
__block int x = 10;
+ ^{ (void)x; };
test2_helper(5, 6, 7);
}
void test2_helper(int x, int y) {
diff --git a/test/CodeGen/indirect-tls-seg-refs.c b/test/CodeGen/indirect-tls-seg-refs.c
new file mode 100644
index 0000000000..de6f3cda7d
--- /dev/null
+++ b/test/CodeGen/indirect-tls-seg-refs.c
@@ -0,0 +1,10 @@
+// REQUIRES: x86-registered-target
+
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-unknown-linux -o - -mno-tls-direct-seg-refs | FileCheck %s -check-prefix=NO-TLSDIRECT
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-unknown-linux -o - | FileCheck %s -check-prefix=TLSDIRECT
+
+// NO-TLSDIRECT: attributes #{{[0-9]+}} = {{{.*}} "indirect-tls-seg-refs"
+// TLSDIRECT-NOT: attributes #{{[0-9]+}} = {{{.*}} "indirect-tls-seg-refs"
+
+void test1() {
+}
diff --git a/test/CodeGen/inline-asm-matching-ppc-vsx.c b/test/CodeGen/inline-asm-matching-ppc-vsx.c
new file mode 100644
index 0000000000..a4fabd6881
--- /dev/null
+++ b/test/CodeGen/inline-asm-matching-ppc-vsx.c
@@ -0,0 +1,20 @@
+// REQUIRES: powerpc-registered-target
+
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -target-feature +vsx \
+// RUN: -target-cpu pwr9 -emit-llvm %s -o - | FileCheck %s
+
+// This case is to test VSX register support in the clobbers list for inline asm.
+void testVSX (void) {
+ unsigned int a = 0;
+ unsigned int *dbell=&a;
+ int d;
+ __asm__ __volatile__ (
+ "lxvw4x %%vs32, 0, %2\n\t"
+ "stxvw4x %%vs32, 0, %1"
+ : "=m"(*(volatile unsigned int*)(dbell))
+ : "r" (dbell), "r" (&d)
+ : "vs32"
+ );
+}
+
+// CHECK: call void asm sideeffect "lxvw4x %vs32, 0, $2\0A\09stxvw4x %vs32, 0, $1", "=*m,r,r,~{vs32}"
diff --git a/test/CodeGen/keep-static-consts.cpp b/test/CodeGen/keep-static-consts.cpp
index 3cdac7ad1a..d89f21cf65 100644
--- a/test/CodeGen/keep-static-consts.cpp
+++ b/test/CodeGen/keep-static-consts.cpp
@@ -1,6 +1,11 @@
// RUN: %clang_cc1 -fkeep-static-consts -emit-llvm %s -o - -triple=x86_64-unknown-linux-gnu | FileCheck %s
// CHECK: @_ZL7srcvers = internal constant [4 x i8] c"xyz\00", align 1
-// CHECK: @llvm.used = appending global [1 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL7srcvers, i32 0, i32 0)], section "llvm.metadata"
+// CHECK: @_ZL8srcvers2 = internal constant [4 x i8] c"abc\00", align 1
+// CHECK: @_ZL1N = internal constant i32 2, align 4
+// CHECK: @llvm.used = appending global [4 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL7srcvers, i32 0, i32 0), i8* bitcast (i32* @b to i8*), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL8srcvers2, i32 0, i32 0), i8* bitcast (i32* @_ZL1N to i8*)], section "llvm.metadata"
+
static const char srcvers[] = "xyz";
extern const int b = 1;
+const char srcvers2[] = "abc";
+constexpr int N = 2;
diff --git a/test/CodeGen/mips-zero-sized-struct.c b/test/CodeGen/mips-zero-sized-struct.c
index 217bdb92c6..08ebf9df3e 100644
--- a/test/CodeGen/mips-zero-sized-struct.c
+++ b/test/CodeGen/mips-zero-sized-struct.c
@@ -1,9 +1,23 @@
// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=O32 %s
// RUN: %clang_cc1 -triple mipsel-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=O32 %s
+// RUN: %clang_cc1 -triple mipsisa32r6-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=O32 %s
+// RUN: %clang_cc1 -triple mipsisa32r6el-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=O32 %s
// RUN: %clang_cc1 -triple mips64-unknown-linux-gnu -S -emit-llvm -o - %s -target-abi n32 | FileCheck -check-prefix=N32 %s
// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnu -S -emit-llvm -o - %s -target-abi n32 | FileCheck -check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mipsisa64r6-unknown-linux-gnu -S -emit-llvm -o - %s -target-abi n32 | FileCheck -check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mipsisa64r6el-unknown-linux-gnu -S -emit-llvm -o - %s -target-abi n32 | FileCheck -check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mips64-unknown-linux-gnuabin32 -S -emit-llvm -o - %s | FileCheck -check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnuabin32 -S -emit-llvm -o - %s | FileCheck -check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mipsisa64r6-unknown-linux-gnuabin32 -S -emit-llvm -o - %s | FileCheck -check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mipsisa64r6el-unknown-linux-gnuabin32 -S -emit-llvm -o - %s | FileCheck -check-prefix=N32 %s
// RUN: %clang_cc1 -triple mips64-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
+// RUN: %clang_cc1 -triple mipsisa64r6-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
+// RUN: %clang_cc1 -triple mipsisa64r6el-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
+// RUN: %clang_cc1 -triple mips64-unknown-linux-gnuabi64 -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
+// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnuabi64 -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
+// RUN: %clang_cc1 -triple mipsisa64r6-unknown-linux-gnuabi64 -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
+// RUN: %clang_cc1 -triple mipsisa64r6el-unknown-linux-gnuabi64 -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s
// O32: define void @fn28(%struct.T2* noalias sret %agg.result, i8 signext %arg0)
// N32: define void @fn28(i8 signext %arg0)
diff --git a/test/CodeGen/ms-intrinsics-cpuid.c b/test/CodeGen/ms-intrinsics-cpuid.c
new file mode 100644
index 0000000000..e6666c86e6
--- /dev/null
+++ b/test/CodeGen/ms-intrinsics-cpuid.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
+// RUN: -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
+// RUN: -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s
+
+// intrin.h needs size_t, but -ffreestanding prevents us from getting it from
+// stddef.h. Work around it with this typedef.
+typedef __SIZE_TYPE__ size_t;
+
+#include <intrin.h>
+
+void test__cpuid(int *info, int level) {
+ __cpuid(info, level);
+}
+// CHECK-LABEL: define {{.*}} @test__cpuid(i32* %{{.*}}, i32 %{{.*}})
+// CHECK: call { i32, i32, i32, i32 } asm "cpuid",
+// CHECK-SAME: "={ax},={bx},={cx},={dx},{ax},{cx},~{dirflag},~{fpsr},~{flags}"
+// CHECK-SAME: (i32 %{{.*}}, i32 0)
diff --git a/test/CodeGen/ms-intrinsics-other.c b/test/CodeGen/ms-intrinsics-other.c
index 65d7670584..adc8ac98e5 100644
--- a/test/CodeGen/ms-intrinsics-other.c
+++ b/test/CodeGen/ms-intrinsics-other.c
@@ -148,3 +148,51 @@ LONG test_InterlockedDecrement(LONG volatile *Addend) {
// CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1
// CHECK: ret i32 [[RESULT]]
// CHECK: }
+
+unsigned short test__lzcnt16(unsigned short x) {
+ return __lzcnt16(x);
+}
+// CHECK: i16 @test__lzcnt16
+// CHECK: [[RESULT:%[0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
+// CHECK: ret i16 [[RESULT]]
+// CHECK: }
+
+unsigned int test__lzcnt(unsigned int x) {
+ return __lzcnt(x);
+}
+// CHECK: i32 @test__lzcnt
+// CHECK: [[RESULT:%[0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+// CHECK: ret i32 [[RESULT]]
+// CHECK: }
+
+unsigned __int64 test__lzcnt64(unsigned __int64 x) {
+ return __lzcnt64(x);
+}
+// CHECK: i64 @test__lzcnt64
+// CHECK: [[RESULT:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
+// CHECK: ret i64 [[RESULT]]
+// CHECK: }
+
+unsigned short test__popcnt16(unsigned short x) {
+ return __popcnt16(x);
+}
+// CHECK: i16 @test__popcnt16
+// CHECK: [[RESULT:%[0-9]+]] = tail call i16 @llvm.ctpop.i16(i16 %x)
+// CHECK: ret i16 [[RESULT]]
+// CHECK: }
+
+unsigned int test__popcnt(unsigned int x) {
+ return __popcnt(x);
+}
+// CHECK: i32 @test__popcnt
+// CHECK: [[RESULT:%[0-9]+]] = tail call i32 @llvm.ctpop.i32(i32 %x)
+// CHECK: ret i32 [[RESULT]]
+// CHECK: }
+
+unsigned __int64 test__popcnt64(unsigned __int64 x) {
+ return __popcnt64(x);
+}
+// CHECK: i64 @test__popcnt64
+// CHECK: [[RESULT:%[0-9]+]] = tail call i64 @llvm.ctpop.i64(i64 %x)
+// CHECK: ret i64 [[RESULT]]
+// CHECK: }
diff --git a/test/CodeGen/ms-intrinsics-rotations.c b/test/CodeGen/ms-intrinsics-rotations.c
index 735de6e41e..30428b12aa 100644
--- a/test/CodeGen/ms-intrinsics-rotations.c
+++ b/test/CodeGen/ms-intrinsics-rotations.c
@@ -30,66 +30,36 @@ unsigned char test_rotl8(unsigned char value, unsigned char shift) {
return _rotl8(value, shift);
}
// CHECK: i8 @test_rotl8
-// CHECK: [[LSHIFT:%[0-9]+]] = and i8 [[SHIFT:%[0-9]+]], 7
-// CHECK: [[HIGH:%[0-9]+]] = shl i8 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i8 0, [[SHIFT]]
-// CHECK: [[RSHIFT:%[0-9]+]] = and i8 [[NEGATE]], 7
-// CHECK: [[LOW:%[0-9]+]] = lshr i8 [[VALUE]], [[RSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i8 [[HIGH]], [[LOW]]
-// CHECK: ret i8 [[RESULT]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+// CHECK: ret i8 [[R]]
unsigned short test_rotl16(unsigned short value, unsigned char shift) {
return _rotl16(value, shift);
}
// CHECK: i16 @test_rotl16
-// CHECK: [[LSHIFT:%[0-9]+]] = and i16 [[SHIFT:%[0-9]+]], 15
-// CHECK: [[HIGH:%[0-9]+]] = shl i16 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i16 0, [[SHIFT]]
-// CHECK: [[RSHIFT:%[0-9]+]] = and i16 [[NEGATE]], 15
-// CHECK: [[LOW:%[0-9]+]] = lshr i16 [[VALUE]], [[RSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i16 [[HIGH]], [[LOW]]
-// CHECK: ret i16 [[RESULT]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK: ret i16 [[R]]
unsigned int test_rotl(unsigned int value, int shift) {
return _rotl(value, shift);
}
// CHECK: i32 @test_rotl
-// CHECK: [[LSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK: [[HIGH:%[0-9]+]] = shl i32 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK: [[RSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK: [[LOW:%[0-9]+]] = lshr i32 [[VALUE]], [[RSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK: ret i32 [[RESULT]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK: ret i32 [[R]]
unsigned LONG test_lrotl(unsigned LONG value, int shift) {
return _lrotl(value, shift);
}
// CHECK-32BIT-LONG: i32 @test_lrotl
-// CHECK-32BIT-LONG: [[LSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK-32BIT-LONG: [[HIGH:%[0-9]+]] = shl i32 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK-32BIT-LONG: [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK-32BIT-LONG: [[RSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK-32BIT-LONG: [[LOW:%[0-9]+]] = lshr i32 [[VALUE]], [[RSHIFT]]
-// CHECK-32BIT-LONG: [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK-32BIT-LONG: ret i32 [[RESULT]]
-// CHECK-32BIT-LONG }
+// CHECK-32BIT-LONG: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK-32BIT-LONG: ret i32 [[R]]
unsigned __int64 test_rotl64(unsigned __int64 value, int shift) {
return _rotl64(value, shift);
}
// CHECK: i64 @test_rotl64
-// CHECK: [[LSHIFT:%[0-9]+]] = and i64 [[SHIFT:%[0-9]+]], 63
-// CHECK: [[HIGH:%[0-9]+]] = shl i64 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i64 0, [[SHIFT]]
-// CHECK: [[RSHIFT:%[0-9]+]] = and i64 [[NEGATE]], 63
-// CHECK: [[LOW:%[0-9]+]] = lshr i64 [[VALUE]], [[RSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i64 [[HIGH]], [[LOW]]
-// CHECK: ret i64 [[RESULT]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK: ret i64 [[R]]
// rotate right
@@ -97,61 +67,34 @@ unsigned char test_rotr8(unsigned char value, unsigned char shift) {
return _rotr8(value, shift);
}
// CHECK: i8 @test_rotr8
-// CHECK: [[RSHIFT:%[0-9]+]] = and i8 [[SHIFT:%[0-9]+]], 7
-// CHECK: [[LOW:%[0-9]+]] = lshr i8 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i8 0, [[SHIFT]]
-// CHECK: [[LSHIFT:%[0-9]+]] = and i8 [[NEGATE]], 7
-// CHECK: [[HIGH:%[0-9]+]] = shl i8 [[VALUE]], [[LSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i8 [[HIGH]], [[LOW]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+// CHECK: ret i8 [[R]]
unsigned short test_rotr16(unsigned short value, unsigned char shift) {
return _rotr16(value, shift);
}
// CHECK: i16 @test_rotr16
-// CHECK: [[RSHIFT:%[0-9]+]] = and i16 [[SHIFT:%[0-9]+]], 15
-// CHECK: [[LOW:%[0-9]+]] = lshr i16 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i16 0, [[SHIFT]]
-// CHECK: [[LSHIFT:%[0-9]+]] = and i16 [[NEGATE]], 15
-// CHECK: [[HIGH:%[0-9]+]] = shl i16 [[VALUE]], [[LSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i16 [[HIGH]], [[LOW]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK: ret i16 [[R]]
unsigned int test_rotr(unsigned int value, int shift) {
return _rotr(value, shift);
}
// CHECK: i32 @test_rotr
-// CHECK: [[RSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK: [[LOW:%[0-9]+]] = lshr i32 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK: [[LSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK: [[HIGH:%[0-9]+]] = shl i32 [[VALUE]], [[LSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK: ret i32 [[RESULT]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK: ret i32 [[R]]
unsigned LONG test_lrotr(unsigned LONG value, int shift) {
return _lrotr(value, shift);
}
// CHECK-32BIT-LONG: i32 @test_lrotr
-// CHECK-32BIT-LONG: [[RSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK-32BIT-LONG: [[LOW:%[0-9]+]] = lshr i32 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK-32BIT-LONG: [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK-32BIT-LONG: [[LSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK-32BIT-LONG: [[HIGH:%[0-9]+]] = shl i32 [[VALUE]], [[LSHIFT]]
-// CHECK-32BIT-LONG: [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK-32BIT-LONG: ret i32 [[RESULT]]
-// CHECK-32BIT-LONG }
+// CHECK-32BIT-LONG: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK-32BIT-LONG: ret i32 [[R]]
unsigned __int64 test_rotr64(unsigned __int64 value, int shift) {
return _rotr64(value, shift);
}
// CHECK: i64 @test_rotr64
-// CHECK: [[RSHIFT:%[0-9]+]] = and i64 [[SHIFT:%[0-9]+]], 63
-// CHECK: [[LOW:%[0-9]+]] = lshr i64 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK: [[NEGATE:%[0-9]+]] = sub i64 0, [[SHIFT]]
-// CHECK: [[LSHIFT:%[0-9]+]] = and i64 [[NEGATE]], 63
-// CHECK: [[HIGH:%[0-9]+]] = shl i64 [[VALUE]], [[LSHIFT]]
-// CHECK: [[RESULT:%[0-9]+]] = or i64 [[HIGH]], [[LOW]]
-// CHECK: ret i64 [[RESULT]]
-// CHECK }
+// CHECK: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK: ret i64 [[R]]
+
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
index bc0b46fc40..e59b1d36a8 100644
--- a/test/CodeGen/ms-intrinsics.c
+++ b/test/CodeGen/ms-intrinsics.c
@@ -3,13 +3,13 @@
// RUN: | FileCheck %s -check-prefixes CHECK,CHECK-I386,CHECK-INTEL
// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
// RUN: -triple thumbv7--windows -Oz -emit-llvm %s -o - \
-// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-X64
+// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-ARM64,CHECK-ARM-X64
// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
// RUN: -triple x86_64--windows -Oz -emit-llvm -target-feature +cx16 %s -o - \
// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL
// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
// RUN: -triple aarch64-windows -Oz -emit-llvm %s -o - \
-// RUN: | FileCheck %s --check-prefix CHECK-ARM-X64
+// RUN: | FileCheck %s --check-prefixes CHECK-ARM-ARM64,CHECK-ARM-X64
// intrin.h needs size_t, but -ffreestanding prevents us from getting it from
// stddef.h. Work around it with this typedef.
@@ -137,7 +137,7 @@ void *test_ReturnAddress() {
// CHECK: = tail call i8* @llvm.returnaddress(i32 0)
// CHECK: ret i8*
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined (__aarch64__)
void *test_AddressOfReturnAddress() {
return _AddressOfReturnAddress();
}
@@ -235,6 +235,21 @@ void *test_InterlockedCompareExchangePointer(void * volatile *Destination,
// CHECK: ret i8* %[[RESULT:[0-9]+]]
// CHECK: }
+void *test_InterlockedCompareExchangePointer_nf(void * volatile *Destination,
+ void *Exchange, void *Comparand) {
+ return _InterlockedCompareExchangePointer_nf(Destination, Exchange, Comparand);
+}
+
+// CHECK: define{{.*}}i8* @test_InterlockedCompareExchangePointer_nf(i8** {{[a-z_ ]*}}%Destination, i8* {{[a-z_ ]*}}%Exchange, i8* {{[a-z_ ]*}}%Comparand){{.*}}{
+// CHECK: %[[DEST:[0-9]+]] = bitcast i8** %Destination to [[iPTR]]*
+// CHECK: %[[EXCHANGE:[0-9]+]] = ptrtoint i8* %Exchange to [[iPTR]]
+// CHECK: %[[COMPARAND:[0-9]+]] = ptrtoint i8* %Comparand to [[iPTR]]
+// CHECK: %[[XCHG:[0-9]+]] = cmpxchg volatile [[iPTR]]* %[[DEST:[0-9]+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] monotonic monotonic
+// CHECK: %[[EXTRACT:[0-9]+]] = extractvalue { [[iPTR]], i1 } %[[XCHG]], 0
+// CHECK: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXTRACT]] to i8*
+// CHECK: ret i8* %[[RESULT:[0-9]+]]
+// CHECK: }
+
char test_InterlockedExchange8(char volatile *value, char mask) {
return _InterlockedExchange8(value, mask);
}
@@ -597,6 +612,736 @@ __int64 test_InterlockedCompareExchange64_HLERelease(__int64 volatile *Destinati
}
#endif
+#if defined(__arm__) || defined(__aarch64__)
+char test_InterlockedExchangeAdd8_acq(char volatile *value, char mask) {
+ return _InterlockedExchangeAdd8_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_acq(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask acquire
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+char test_InterlockedExchangeAdd8_rel(char volatile *value, char mask) {
+ return _InterlockedExchangeAdd8_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_rel(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask release
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+char test_InterlockedExchangeAdd8_nf(char volatile *value, char mask) {
+ return _InterlockedExchangeAdd8_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_nf(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask monotonic
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+short test_InterlockedExchangeAdd16_acq(short volatile *value, short mask) {
+ return _InterlockedExchangeAdd16_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_acq(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask acquire
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+short test_InterlockedExchangeAdd16_rel(short volatile *value, short mask) {
+ return _InterlockedExchangeAdd16_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_rel(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask release
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+short test_InterlockedExchangeAdd16_nf(short volatile *value, short mask) {
+ return _InterlockedExchangeAdd16_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_nf(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask monotonic
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+long test_InterlockedExchangeAdd_acq(long volatile *value, long mask) {
+ return _InterlockedExchangeAdd_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_acq(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask acquire
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+long test_InterlockedExchangeAdd_rel(long volatile *value, long mask) {
+ return _InterlockedExchangeAdd_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_rel(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask release
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+long test_InterlockedExchangeAdd_nf(long volatile *value, long mask) {
+ return _InterlockedExchangeAdd_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_nf(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask monotonic
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+__int64 test_InterlockedExchangeAdd64_acq(__int64 volatile *value, __int64 mask) {
+ return _InterlockedExchangeAdd64_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_acq(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask acquire
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+__int64 test_InterlockedExchangeAdd64_rel(__int64 volatile *value, __int64 mask) {
+ return _InterlockedExchangeAdd64_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_rel(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask release
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+__int64 test_InterlockedExchangeAdd64_nf(__int64 volatile *value, __int64 mask) {
+ return _InterlockedExchangeAdd64_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_nf(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask monotonic
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedExchange8_acq(char volatile *value, char mask) {
+ return _InterlockedExchange8_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_acq(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i8* %value, i8 %mask acquire
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+char test_InterlockedExchange8_rel(char volatile *value, char mask) {
+ return _InterlockedExchange8_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_rel(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i8* %value, i8 %mask release
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+char test_InterlockedExchange8_nf(char volatile *value, char mask) {
+ return _InterlockedExchange8_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_nf(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i8* %value, i8 %mask monotonic
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+short test_InterlockedExchange16_acq(short volatile *value, short mask) {
+ return _InterlockedExchange16_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_acq(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i16* %value, i16 %mask acquire
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+short test_InterlockedExchange16_rel(short volatile *value, short mask) {
+ return _InterlockedExchange16_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_rel(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i16* %value, i16 %mask release
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+short test_InterlockedExchange16_nf(short volatile *value, short mask) {
+ return _InterlockedExchange16_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_nf(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i16* %value, i16 %mask monotonic
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+long test_InterlockedExchange_acq(long volatile *value, long mask) {
+ return _InterlockedExchange_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_acq(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i32* %value, i32 %mask acquire
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+long test_InterlockedExchange_rel(long volatile *value, long mask) {
+ return _InterlockedExchange_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_rel(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i32* %value, i32 %mask release
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+long test_InterlockedExchange_nf(long volatile *value, long mask) {
+ return _InterlockedExchange_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_nf(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i32* %value, i32 %mask monotonic
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+__int64 test_InterlockedExchange64_acq(__int64 volatile *value, __int64 mask) {
+ return _InterlockedExchange64_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_acq(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i64* %value, i64 %mask acquire
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+__int64 test_InterlockedExchange64_rel(__int64 volatile *value, __int64 mask) {
+ return _InterlockedExchange64_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_rel(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i64* %value, i64 %mask release
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+__int64 test_InterlockedExchange64_nf(__int64 volatile *value, __int64 mask) {
+ return _InterlockedExchange64_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_nf(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg i64* %value, i64 %mask monotonic
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedCompareExchange8_acq(char volatile *Destination, char Exchange, char Comperand) {
+ return _InterlockedCompareExchange8_acq(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_acq(i8*{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i8* %Destination, i8 %Comperand, i8 %Exchange acquire acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i8 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedCompareExchange8_rel(char volatile *Destination, char Exchange, char Comperand) {
+ return _InterlockedCompareExchange8_rel(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_rel(i8*{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i8* %Destination, i8 %Comperand, i8 %Exchange release monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i8 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedCompareExchange8_nf(char volatile *Destination, char Exchange, char Comperand) {
+ return _InterlockedCompareExchange8_nf(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_nf(i8*{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i8* %Destination, i8 %Comperand, i8 %Exchange monotonic monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i8 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedCompareExchange16_acq(short volatile *Destination, short Exchange, short Comperand) {
+ return _InterlockedCompareExchange16_acq(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_acq(i16*{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i16* %Destination, i16 %Comperand, i16 %Exchange acquire acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedCompareExchange16_rel(short volatile *Destination, short Exchange, short Comperand) {
+ return _InterlockedCompareExchange16_rel(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_rel(i16*{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i16* %Destination, i16 %Comperand, i16 %Exchange release monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedCompareExchange16_nf(short volatile *Destination, short Exchange, short Comperand) {
+ return _InterlockedCompareExchange16_nf(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_nf(i16*{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i16* %Destination, i16 %Comperand, i16 %Exchange monotonic monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedCompareExchange_acq(long volatile *Destination, long Exchange, long Comperand) {
+ return _InterlockedCompareExchange_acq(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_acq(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i32* %Destination, i32 %Comperand, i32 %Exchange acquire acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedCompareExchange_rel(long volatile *Destination, long Exchange, long Comperand) {
+ return _InterlockedCompareExchange_rel(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_rel(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i32* %Destination, i32 %Comperand, i32 %Exchange release monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedCompareExchange_nf(long volatile *Destination, long Exchange, long Comperand) {
+ return _InterlockedCompareExchange_nf(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_nf(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i32* %Destination, i32 %Comperand, i32 %Exchange monotonic monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedCompareExchange64_acq(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) {
+ return _InterlockedCompareExchange64_acq(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_acq(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i64* %Destination, i64 %Comperand, i64 %Exchange acquire acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedCompareExchange64_rel(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) {
+ return _InterlockedCompareExchange64_rel(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_rel(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i64* %Destination, i64 %Comperand, i64 %Exchange release monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedCompareExchange64_nf(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) {
+ return _InterlockedCompareExchange64_nf(Destination, Exchange, Comperand);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_nf(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile i64* %Destination, i64 %Comperand, i64 %Exchange monotonic monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedOr8_acq(char volatile *value, char mask) {
+ return _InterlockedOr8_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_acq(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i8* %value, i8 %mask acquire
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedOr8_rel(char volatile *value, char mask) {
+ return _InterlockedOr8_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_rel(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i8* %value, i8 %mask release
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedOr8_nf(char volatile *value, char mask) {
+ return _InterlockedOr8_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_nf(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i8* %value, i8 %mask monotonic
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedOr16_acq(short volatile *value, short mask) {
+ return _InterlockedOr16_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_acq(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i16* %value, i16 %mask acquire
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedOr16_rel(short volatile *value, short mask) {
+ return _InterlockedOr16_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_rel(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i16* %value, i16 %mask release
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedOr16_nf(short volatile *value, short mask) {
+ return _InterlockedOr16_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_nf(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i16* %value, i16 %mask monotonic
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedOr_acq(long volatile *value, long mask) {
+ return _InterlockedOr_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_acq(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i32* %value, i32 %mask acquire
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedOr_rel(long volatile *value, long mask) {
+ return _InterlockedOr_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_rel(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i32* %value, i32 %mask release
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedOr_nf(long volatile *value, long mask) {
+ return _InterlockedOr_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_nf(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i32* %value, i32 %mask monotonic
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedOr64_acq(__int64 volatile *value, __int64 mask) {
+ return _InterlockedOr64_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_acq(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i64* %value, i64 %mask acquire
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedOr64_rel(__int64 volatile *value, __int64 mask) {
+ return _InterlockedOr64_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_rel(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i64* %value, i64 %mask release
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedOr64_nf(__int64 volatile *value, __int64 mask) {
+ return _InterlockedOr64_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_nf(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or i64* %value, i64 %mask monotonic
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedXor8_acq(char volatile *value, char mask) {
+ return _InterlockedXor8_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_acq(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i8* %value, i8 %mask acquire
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedXor8_rel(char volatile *value, char mask) {
+ return _InterlockedXor8_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_rel(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i8* %value, i8 %mask release
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedXor8_nf(char volatile *value, char mask) {
+ return _InterlockedXor8_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_nf(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i8* %value, i8 %mask monotonic
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedXor16_acq(short volatile *value, short mask) {
+ return _InterlockedXor16_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_acq(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i16* %value, i16 %mask acquire
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedXor16_rel(short volatile *value, short mask) {
+ return _InterlockedXor16_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_rel(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i16* %value, i16 %mask release
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedXor16_nf(short volatile *value, short mask) {
+ return _InterlockedXor16_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_nf(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i16* %value, i16 %mask monotonic
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedXor_acq(long volatile *value, long mask) {
+ return _InterlockedXor_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_acq(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i32* %value, i32 %mask acquire
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedXor_rel(long volatile *value, long mask) {
+ return _InterlockedXor_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_rel(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i32* %value, i32 %mask release
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedXor_nf(long volatile *value, long mask) {
+ return _InterlockedXor_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_nf(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i32* %value, i32 %mask monotonic
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedXor64_acq(__int64 volatile *value, __int64 mask) {
+ return _InterlockedXor64_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_acq(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i64* %value, i64 %mask acquire
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedXor64_rel(__int64 volatile *value, __int64 mask) {
+ return _InterlockedXor64_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_rel(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i64* %value, i64 %mask release
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedXor64_nf(__int64 volatile *value, __int64 mask) {
+ return _InterlockedXor64_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_nf(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor i64* %value, i64 %mask monotonic
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedAnd8_acq(char volatile *value, char mask) {
+ return _InterlockedAnd8_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_acq(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i8* %value, i8 %mask acquire
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedAnd8_rel(char volatile *value, char mask) {
+ return _InterlockedAnd8_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_rel(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i8* %value, i8 %mask release
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+char test_InterlockedAnd8_nf(char volatile *value, char mask) {
+ return _InterlockedAnd8_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_nf(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i8* %value, i8 %mask monotonic
+// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedAnd16_acq(short volatile *value, short mask) {
+ return _InterlockedAnd16_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_acq(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i16* %value, i16 %mask acquire
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedAnd16_rel(short volatile *value, short mask) {
+ return _InterlockedAnd16_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_rel(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i16* %value, i16 %mask release
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedAnd16_nf(short volatile *value, short mask) {
+ return _InterlockedAnd16_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_nf(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i16* %value, i16 %mask monotonic
+// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedAnd_acq(long volatile *value, long mask) {
+ return _InterlockedAnd_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_acq(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i32* %value, i32 %mask acquire
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedAnd_rel(long volatile *value, long mask) {
+ return _InterlockedAnd_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_rel(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i32* %value, i32 %mask release
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedAnd_nf(long volatile *value, long mask) {
+ return _InterlockedAnd_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_nf(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i32* %value, i32 %mask monotonic
+// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedAnd64_acq(__int64 volatile *value, __int64 mask) {
+ return _InterlockedAnd64_acq(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_acq(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i64* %value, i64 %mask acquire
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedAnd64_rel(__int64 volatile *value, __int64 mask) {
+ return _InterlockedAnd64_rel(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_rel(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i64* %value, i64 %mask release
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedAnd64_nf(__int64 volatile *value, __int64 mask) {
+ return _InterlockedAnd64_nf(value, mask);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_nf(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and i64* %value, i64 %mask monotonic
+// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedIncrement16_acq(short volatile *Addend) {
+ return _InterlockedIncrement16_acq(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_acq(i16*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i16* %Addend, i16 1 acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedIncrement16_rel(short volatile *Addend) {
+ return _InterlockedIncrement16_rel(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_rel(i16*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i16* %Addend, i16 1 release
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedIncrement16_nf(short volatile *Addend) {
+ return _InterlockedIncrement16_nf(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_nf(i16*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i16* %Addend, i16 1 monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedIncrement_acq(long volatile *Addend) {
+ return _InterlockedIncrement_acq(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_acq(i32*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i32* %Addend, i32 1 acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedIncrement_rel(long volatile *Addend) {
+ return _InterlockedIncrement_rel(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_rel(i32*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i32* %Addend, i32 1 release
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedIncrement_nf(long volatile *Addend) {
+ return _InterlockedIncrement_nf(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_nf(i32*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i32* %Addend, i32 1 monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedIncrement64_acq(__int64 volatile *Addend) {
+ return _InterlockedIncrement64_acq(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_acq(i64*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i64* %Addend, i64 1 acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedIncrement64_rel(__int64 volatile *Addend) {
+ return _InterlockedIncrement64_rel(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_rel(i64*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i64* %Addend, i64 1 release
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedIncrement64_nf(__int64 volatile *Addend) {
+ return _InterlockedIncrement64_nf(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_nf(i64*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add i64* %Addend, i64 1 monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedDecrement16_acq(short volatile *Addend) {
+ return _InterlockedDecrement16_acq(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_acq(i16*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i16* %Addend, i16 1 acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedDecrement16_rel(short volatile *Addend) {
+ return _InterlockedDecrement16_rel(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_rel(i16*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i16* %Addend, i16 1 release
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+short test_InterlockedDecrement16_nf(short volatile *Addend) {
+ return _InterlockedDecrement16_nf(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_nf(i16*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i16* %Addend, i16 1 monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i16 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedDecrement_acq(long volatile *Addend) {
+ return _InterlockedDecrement_acq(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_acq(i32*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i32* %Addend, i32 1 acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedDecrement_rel(long volatile *Addend) {
+ return _InterlockedDecrement_rel(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_rel(i32*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i32* %Addend, i32 1 release
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+long test_InterlockedDecrement_nf(long volatile *Addend) {
+ return _InterlockedDecrement_nf(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_nf(i32*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i32* %Addend, i32 1 monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i32 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedDecrement64_acq(__int64 volatile *Addend) {
+ return _InterlockedDecrement64_acq(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_acq(i64*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i64* %Addend, i64 1 acquire
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedDecrement64_rel(__int64 volatile *Addend) {
+ return _InterlockedDecrement64_rel(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_rel(i64*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i64* %Addend, i64 1 release
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+
+__int64 test_InterlockedDecrement64_nf(__int64 volatile *Addend) {
+ return _InterlockedDecrement64_nf(Addend);
+}
+// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_nf(i64*{{[a-z_ ]*}}%Addend){{.*}}{
+// CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub i64* %Addend, i64 1 monotonic
+// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1
+// CHECK-ARM-ARM64: ret i64 [[RESULT]]
+// CHECK-ARM-ARM64: }
+#endif
+
#if !defined(__aarch64__)
void test__fastfail() {
__fastfail(42);
diff --git a/test/CodeGen/ms-setjmp.c b/test/CodeGen/ms-setjmp.c
index d92f4d00ff..a6e30cb96a 100644
--- a/test/CodeGen/ms-setjmp.c
+++ b/test/CodeGen/ms-setjmp.c
@@ -25,7 +25,7 @@ int test_setjmp() {
// X64-NEXT: ret i32 %[[call]]
// AARCH64-LABEL: define dso_local i32 @test_setjmp
- // AARCH64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
+ // AARCH64: %[[addr:.*]] = call i8* @llvm.sponentry()
// AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
// AARCH64-NEXT: ret i32 %[[call]]
}
@@ -38,7 +38,7 @@ int test_setjmpex() {
// X64-NEXT: ret i32 %[[call]]
// AARCH64-LABEL: define dso_local i32 @test_setjmpex
- // AARCH64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
+ // AARCH64: %[[addr:.*]] = call i8* @llvm.sponentry()
// AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
// AARCH64-NEXT: ret i32 %[[call]]
}
diff --git a/test/CodeGen/personality.c b/test/CodeGen/personality.c
index 1c533ce786..59a6a9ccd6 100644
--- a/test/CodeGen/personality.c
+++ b/test/CodeGen/personality.c
@@ -26,6 +26,7 @@ extern void i(void);
void f(void) {
__block int i;
+ ^{ (void)i; };
g(^ { });
}
diff --git a/test/CodeGen/split-debug-single-file.c b/test/CodeGen/split-debug-single-file.c
new file mode 100644
index 0000000000..ffbc127a46
--- /dev/null
+++ b/test/CodeGen/split-debug-single-file.c
@@ -0,0 +1,17 @@
+// REQUIRES: x86-registered-target
+
+// Testing to ensure -enable-split-dwarf=single allows to place .dwo sections into regular output object.
+// RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \
+// RUN: -enable-split-dwarf=single -split-dwarf-file %t.o -emit-obj -o %t.o %s
+// RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=MODE-SINGLE %s
+// MODE-SINGLE: .dwo
+
+// Testing to ensure -enable-split-dwarf=split does not place .dwo sections into regular output object.
+// RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \
+// RUN: -enable-split-dwarf=split -split-dwarf-file %t.o -emit-obj -o %t.o %s
+// RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=MODE-SPLIT %s
+// MODE-SPLIT-NOT: .dwo
+
+int main (void) {
+ return 0;
+}
diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c
index ac22f5b1c8..005bdfd917 100644
--- a/test/CodeGen/sse2-builtins.c
+++ b/test/CodeGen/sse2-builtins.c
@@ -721,6 +721,30 @@ __m128i test_mm_loadu_si64(void const* A) {
return _mm_loadu_si64(A);
}
+__m128i test_mm_loadu_si32(void const* A) {
+ // CHECK-LABEL: test_mm_loadu_si32
+ // CHECK: load i32, i32* %{{.*}}, align 1{{$}}
+ // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 1
+ // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 2
+ // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 3
+ return _mm_loadu_si32(A);
+}
+
+__m128i test_mm_loadu_si16(void const* A) {
+ // CHECK-LABEL: test_mm_loadu_si16
+ // CHECK: load i16, i16* %{{.*}}, align 1{{$}}
+ // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 1
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 2
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 3
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 4
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 5
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 6
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 7
+ return _mm_loadu_si16(A);
+}
+
__m128i test_mm_madd_epi16(__m128i A, __m128i B) {
// CHECK-LABEL: test_mm_madd_epi16
// CHECK: call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
@@ -1351,6 +1375,30 @@ void test_mm_storeu_si128(__m128i* A, __m128i B) {
_mm_storeu_si128(A, B);
}
+void test_mm_storeu_si64(void* A, __m128i B) {
+ // CHECK-LABEL: test_mm_storeu_si64
+ // CHECK: [[EXT:%.*]] = extractelement <2 x i64> %{{.*}}, i32 0
+ // CHECK: store i64 [[EXT]], i64* %{{.*}}, align 1{{$}}
+ // CHECK-NEXT: ret void
+ _mm_storeu_si64(A, B);
+}
+
+void test_mm_storeu_si32(void* A, __m128i B) {
+ // CHECK-LABEL: test_mm_storeu_si32
+ // CHECK: [[EXT:%.*]] = extractelement <4 x i32> %{{.*}}, i32 0
+ // CHECK: store i32 [[EXT]], i32* %{{.*}}, align 1{{$}}
+ // CHECK-NEXT: ret void
+ _mm_storeu_si32(A, B);
+}
+
+void test_mm_storeu_si16(void* A, __m128i B) {
+ // CHECK-LABEL: test_mm_storeu_si16
+ // CHECK: [[EXT:%.*]] = extractelement <8 x i16> %{{.*}}, i32 0
+ // CHECK: store i16 [[EXT]], i16* %{{.*}}, align 1{{$}}
+ // CHECK-NEXT: ret void
+ _mm_storeu_si16(A, B);
+}
+
void test_mm_stream_pd(double *A, __m128d B) {
// CHECK-LABEL: test_mm_stream_pd
// CHECK: store <2 x double> %{{.*}}, <2 x double>* %{{.*}}, align 16, !nontemporal
diff --git a/test/CodeGen/stack-arg-probe.c b/test/CodeGen/stack-arg-probe.c
index d806db61c3..2ffe1f2862 100644
--- a/test/CodeGen/stack-arg-probe.c
+++ b/test/CodeGen/stack-arg-probe.c
@@ -1,8 +1,15 @@
// RUN: %clang_cc1 %s -triple=i686-windows-msvc -emit-llvm -o - -mno-stack-arg-probe | FileCheck %s -check-prefix=NO-STACKPROBE
+// RUN: %clang_cc1 %s -triple=x86_64-windows-msvc -emit-llvm -o - -mno-stack-arg-probe | FileCheck %s -check-prefix=NO-STACKPROBE
+// RUN: %clang_cc1 %s -triple=armv7-windows-msvc -emit-llvm -o - -mno-stack-arg-probe | FileCheck %s -check-prefix=NO-STACKPROBE
+// RUN: %clang_cc1 %s -triple=aarch64-windows-msvc -emit-llvm -o - -mno-stack-arg-probe | FileCheck %s -check-prefix=NO-STACKPROBE
// RUN: %clang_cc1 %s -triple=i686-windows-msvc -emit-llvm -o - | FileCheck %s -check-prefix=STACKPROBE
+// RUN: %clang_cc1 %s -triple=x86_64-windows-msvc -emit-llvm -o - | FileCheck %s -check-prefix=STACKPROBE
+// RUN: %clang_cc1 %s -triple=armv7-windows-msvc -emit-llvm -o - | FileCheck %s -check-prefix=STACKPROBE
+// RUN: %clang_cc1 %s -triple=aarch64-windows-msvc -emit-llvm -o - | FileCheck %s -check-prefix=STACKPROBE
+
// NO-STACKPROBE: attributes #{{[0-9]+}} = {{{.*}} "no-stack-arg-probe"
-// STACKPROBE-NOT: attributes #{{[0-9]+}} = {{{.*}} "no-stack-arg-probe"
+// STACKPROBE-NOT: "no-stack-arg-probe"
void test1() {
}
diff --git a/test/CodeGen/swift-call-conv.c b/test/CodeGen/swift-call-conv.c
new file mode 100644
index 0000000000..31d70b33a4
--- /dev/null
+++ b/test/CodeGen/swift-call-conv.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s
+
+// REQUIRES: aarch64-registered-target,arm-registered-target,x86-registered-target
+
+void __attribute__((__swiftcall__)) f(void) {}
+// CHECK-LABEL: define dso_local swiftcc void @f()
+
diff --git a/test/CodeGen/target-builtin-noerror.c b/test/CodeGen/target-builtin-noerror.c
index 37820b33ba..400c5e696a 100644
--- a/test/CodeGen/target-builtin-noerror.c
+++ b/test/CodeGen/target-builtin-noerror.c
@@ -75,6 +75,11 @@ void verifyfeaturestrings() {
(void)__builtin_cpu_supports("avx5124vnniw");
(void)__builtin_cpu_supports("avx5124fmaps");
(void)__builtin_cpu_supports("avx512vpopcntdq");
+ (void)__builtin_cpu_supports("avx512vbmi2");
+ (void)__builtin_cpu_supports("gfni");
+ (void)__builtin_cpu_supports("vpclmulqdq");
+ (void)__builtin_cpu_supports("avx512vnni");
+ (void)__builtin_cpu_supports("avx512bitalg");
}
void verifycpustrings() {
@@ -95,7 +100,11 @@ void verifycpustrings() {
(void)__builtin_cpu_is("cannonlake");
(void)__builtin_cpu_is("core2");
(void)__builtin_cpu_is("corei7");
+ (void)__builtin_cpu_is("goldmont");
+ (void)__builtin_cpu_is("goldmont-plus");
(void)__builtin_cpu_is("haswell");
+ (void)__builtin_cpu_is("icelake-client");
+ (void)__builtin_cpu_is("icelake-server");
(void)__builtin_cpu_is("intel");
(void)__builtin_cpu_is("istanbul");
(void)__builtin_cpu_is("ivybridge");
@@ -108,6 +117,7 @@ void verifycpustrings() {
(void)__builtin_cpu_is("skylake");
(void)__builtin_cpu_is("skylake-avx512");
(void)__builtin_cpu_is("slm");
+ (void)__builtin_cpu_is("tremont");
(void)__builtin_cpu_is("westmere");
(void)__builtin_cpu_is("znver1");
}
diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c
index 166f6002a1..0c2b1e4cff 100644
--- a/test/CodeGen/target-data.c
+++ b/test/CodeGen/target-data.c
@@ -32,26 +32,54 @@
// RUN: %clang_cc1 -triple mipsel-linux-gnu -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=MIPS-32EL
+// RUN: %clang_cc1 -triple mipsisa32r6el-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-32EL
// MIPS-32EL: target datalayout = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
// RUN: %clang_cc1 -triple mips-linux-gnu -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=MIPS-32EB
+// RUN: %clang_cc1 -triple mipsisa32r6-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-32EB
// MIPS-32EB: target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
// RUN: %clang_cc1 -triple mips64el-linux-gnu -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=MIPS-64EL
+// RUN: %clang_cc1 -triple mips64el-linux-gnuabi64 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EL
+// RUN: %clang_cc1 -triple mipsisa64r6el-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EL
+// RUN: %clang_cc1 -triple mipsisa64r6el-linux-gnuabi64 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EL
// MIPS-64EL: target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
// RUN: %clang_cc1 -triple mips64el-linux-gnu -o - -emit-llvm -target-abi n32 \
// RUN: %s | FileCheck %s -check-prefix=MIPS-64EL-N32
+// RUN: %clang_cc1 -triple mips64el-linux-gnuabin32 -o - -emit-llvm \
+// RUN: %s | FileCheck %s -check-prefix=MIPS-64EL-N32
+// RUN: %clang_cc1 -triple mipsisa64r6el-linux-gnu -o - -emit-llvm -target-abi n32 \
+// RUN: %s | FileCheck %s -check-prefix=MIPS-64EL-N32
+// RUN: %clang_cc1 -triple mipsisa64r6el-linux-gnuabin32 -o - -emit-llvm \
+// RUN: %s | FileCheck %s -check-prefix=MIPS-64EL-N32
// MIPS-64EL-N32: target datalayout = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"
// RUN: %clang_cc1 -triple mips64-linux-gnu -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=MIPS-64EB
+// RUN: %clang_cc1 -triple mips64-linux-gnuabi64 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EB
+// RUN: %clang_cc1 -triple mipsisa64r6-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EB
+// RUN: %clang_cc1 -triple mipsisa64r6-linux-gnuabi64 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EB
// MIPS-64EB: target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
// RUN: %clang_cc1 -triple mips64-linux-gnu -o - -emit-llvm %s -target-abi n32 \
// RUN: | FileCheck %s -check-prefix=MIPS-64EB-N32
+// RUN: %clang_cc1 -triple mips64-linux-gnuabin32 -o - -emit-llvm %s \
+// RUN: | FileCheck %s -check-prefix=MIPS-64EB-N32
+// RUN: %clang_cc1 -triple mipsisa64r6-linux-gnu -o - -emit-llvm %s -target-abi n32 \
+// RUN: | FileCheck %s -check-prefix=MIPS-64EB-N32
+// RUN: %clang_cc1 -triple mipsisa64r6-linux-gnuabin32 -o - -emit-llvm %s \
+// RUN: | FileCheck %s -check-prefix=MIPS-64EB-N32
// MIPS-64EB-N32: target datalayout = "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"
// RUN: %clang_cc1 -triple powerpc64-lv2 -o - -emit-llvm %s | \
@@ -151,6 +179,10 @@
// RUN: %s | FileCheck %s -check-prefix=ARM-GNU
// ARM-GNU: target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+// RUN: %clang_cc1 -triple arc-unknown-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=ARC
+// ARC: target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32"
+
// RUN: %clang_cc1 -triple hexagon-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=HEXAGON
// HEXAGON: target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
diff --git a/test/CodeGen/thinlto-distributed-cfi-devirt.ll b/test/CodeGen/thinlto-distributed-cfi-devirt.ll
index ab33a59b69..fbcaa773ba 100644
--- a/test/CodeGen/thinlto-distributed-cfi-devirt.ll
+++ b/test/CodeGen/thinlto-distributed-cfi-devirt.ll
@@ -6,7 +6,9 @@
; RUN: opt -thinlto-bc -o %t.o %s
+; FIXME: Fix machine verifier issues and remove -verify-machineinstrs=0. PR39436.
; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \
+; RUN: -verify-machineinstrs=0 \
; RUN: -o %t2.index \
; RUN: -r=%t.o,test,px \
; RUN: -r=%t.o,_ZN1A1nEi,p \
diff --git a/test/CodeGen/thinlto_backend.ll b/test/CodeGen/thinlto_backend.ll
index 5ba846457d..2dd919d5f7 100644
--- a/test/CodeGen/thinlto_backend.ll
+++ b/test/CodeGen/thinlto_backend.ll
@@ -25,7 +25,8 @@
; be empty file.
; RUN: opt -o %t5.o %s
; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t4.o -x ir %t5.o -c -fthinlto-index=%t.thinlto.bc
-; RUN: llvm-nm %t4.o | count 0
+; RUN: llvm-nm %t4.o 2>&1 | FileCheck %s -check-prefix=NO-SYMBOLS
+; NO-SYMBOLS: no symbols
; Ensure f2 was imported. Check for all 3 flavors of -save-temps[=cwd|obj].
; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc -save-temps=obj
diff --git a/test/CodeGen/thinlto_backend_local_name_conflict.ll b/test/CodeGen/thinlto_backend_local_name_conflict.ll
new file mode 100644
index 0000000000..cefbc51bf0
--- /dev/null
+++ b/test/CodeGen/thinlto_backend_local_name_conflict.ll
@@ -0,0 +1,36 @@
+; Test handling when two files with the same source file name contain
+; static read only variables with the same name (which will have the same GUID
+; in the combined index).
+
+; REQUIRES: x86-registered-target
+
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: opt -module-summary -module-hash %s -o %t.bc
+; RUN: opt -module-summary -module-hash %p/Inputs/thinlto_backend_local_name_conflict1.ll -o %t2.bc
+; RUN: opt -module-summary -module-hash %p/Inputs/thinlto_backend_local_name_conflict2.ll -o %t3.bc
+; RUN: llvm-lto -thinlto-action=thinlink -o %t4.bc %t.bc %t2.bc %t3.bc
+; RUN: llvm-lto -thinlto-action=distributedindexes -exported-symbol=main -thinlto-index=%t4.bc %t.bc
+
+; This module will import a() and b() which should cause the read only copy
+; of baz from each of those modules to be imported. Check that the both are
+; imported as local copies.
+; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t4.o -x ir %t.bc -c -fthinlto-index=%t.bc.thinlto.bc -save-temps=obj
+; RUN: llvm-dis %t.s.3.import.bc -o - | FileCheck --check-prefix=IMPORT %s
+; IMPORT: @baz.llvm.{{.*}} = internal global i32 10
+; IMPORT: @baz.llvm.{{.*}} = internal global i32 10
+
+; ModuleID = 'local_name_conflict_var_main.o'
+source_filename = "local_name_conflict_var_main.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: noinline nounwind uwtable
+define i32 @main() {
+entry:
+ %call1 = call i32 (...) @a()
+ %call2 = call i32 (...) @b()
+ ret i32 0
+}
+
+declare i32 @a(...)
+declare i32 @b(...)
diff --git a/test/CodeGen/ubsan-debuglog-return.c b/test/CodeGen/ubsan-debuglog-return.c
new file mode 100644
index 0000000000..23a1326934
--- /dev/null
+++ b/test/CodeGen/ubsan-debuglog-return.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -x c -debug-info-kind=line-tables-only -emit-llvm -fsanitize=returns-nonnull-attribute -o - %s | FileCheck %s
+// The UBSAN function call in the epilogue needs to have a debug location.
+
+__attribute__((returns_nonnull)) void *allocate() {}
+
+// CHECK: define {{.*}}nonnull i8* @allocate(){{.*}} !dbg
+// CHECK: call void @__ubsan_handle_nonnull_return_v1_abort
+// CHECK-SAME: !dbg ![[LOC:[0-9]+]]
+// CHECK: ret i8*
+// CHECK-SAME: !dbg ![[LOC]]
diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c
index c79cd84f7e..f128c8a321 100644
--- a/test/CodeGen/vector.c
+++ b/test/CodeGen/vector.c
@@ -70,7 +70,7 @@ vec_int1 lax_vector_compare1(int x, vec_int1 y) {
}
// CHECK: define i32 @lax_vector_compare1(i32 {{.*}}, i32 {{.*}})
-// CHECK: icmp eq <1 x i32>
+// CHECK: icmp eq i32
typedef int vec_int2 __attribute__((vector_size(8)));
vec_int2 lax_vector_compare2(long long x, vec_int2 y) {
diff --git a/test/CodeGen/win64-i128.c b/test/CodeGen/win64-i128.c
new file mode 100644
index 0000000000..0514c4846c
--- /dev/null
+++ b/test/CodeGen/win64-i128.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=GNU64
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=MSC64
+
+typedef int int128_t __attribute__((mode(TI)));
+
+int128_t foo() { return 0; }
+
+// GNU64: define dso_local <2 x i64> @foo()
+// MSC64: define dso_local <2 x i64> @foo()
+
+int128_t bar(int128_t a, int128_t b) { return a * b; }
+
+// GNU64: define dso_local <2 x i64> @bar(i128*, i128*)
+// MSC64: define dso_local <2 x i64> @bar(i128*, i128*)
diff --git a/test/CodeGen/windows-swiftcall.c b/test/CodeGen/windows-swiftcall.c
index d8fdec47aa..98fb3bd4b5 100644
--- a/test/CodeGen/windows-swiftcall.c
+++ b/test/CodeGen/windows-swiftcall.c
@@ -5,7 +5,7 @@
#define ERROR __attribute__((swift_error_result))
#define CONTEXT __attribute__((swift_context))
-// CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, float 0.000000e+00, float 0.000000e+00 }
+// CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, i32 0, i32 0 }
/*****************************************************************************/
/****************************** PARAMETER ABIS *******************************/
@@ -93,8 +93,8 @@ typedef struct {
int x;
char c0;
char c1;
- float f0;
- float f1;
+ int f0;
+ int f1;
} struct_1;
TEST(struct_1);
// CHECK-LABEL: define dso_local swiftcc { i64, i64 } @return_struct_1() {{.*}}{
@@ -141,8 +141,8 @@ typedef struct {
int x;
char c0;
__attribute__((aligned(2))) char c1;
- float f0;
- float f1;
+ int f0;
+ int f1;
} struct_2;
TEST(struct_2);
// CHECK-LABEL: define dso_local swiftcc { i64, i64 } @return_struct_2() {{.*}}{
@@ -299,20 +299,30 @@ typedef union {
TEST(union_hom_fp_partial)
// CHECK: define dso_local void @test_union_hom_fp_partial()
// CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16
-// CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_union_hom_fp_partial()
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 0
-// CHECK: store i64 [[T1]], i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 1
-// CHECK: store i64 [[T1]], i64* [[T0]], align 8
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
-// CHECK: [[V0:%.*]] = load i64, i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[V1:%.*]] = load i64, i64* [[T0]], align 8
-// CHECK: call swiftcc void @take_union_hom_fp_partial(i64 [[V0]], i64 [[V1]])
+// CHECK: [[CALL:%.*]] = call swiftcc { float, float, float, float } @return_union_hom_fp_partial()
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { float, float, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 0
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 0
+// CHECK: store float [[T1]], float* [[T0]], align 16
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 1
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 2
+// CHECK: store float [[T1]], float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 3
+// CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 3
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { float, float, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 0
+// CHECK: [[V0:%.*]] = load float, float* [[T0]], align 16
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[V1:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[V2:%.*]] = load float, float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { float, float, float, float }, { float, float, float, float }* [[CAST]], i32 0, i32 3
+// CHECK: [[V3:%.*]] = load float, float* [[T0]], align 4
+// CHECK: call swiftcc void @take_union_hom_fp_partial(float [[V0]], float [[V1]], float [[V2]], float [[V3]])
// CHECK: ret void
// CHECK: }
@@ -323,20 +333,25 @@ typedef union {
TEST(union_het_fpv_partial)
// CHECK-LABEL: define dso_local void @test_union_het_fpv_partial()
// CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16
-// CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_union_het_fpv_partial()
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 0
+// CHECK: [[CALL:%.*]] = call swiftcc { i64, float, float } @return_union_het_fpv_partial()
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 0
+// CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 0
// CHECK: store i64 [[T1]], i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 1
-// CHECK: store i64 [[T1]], i64* [[T0]], align 8
-// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }*
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 1
+// CHECK: store float [[T1]], float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 2
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, float, float }*
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 0
// CHECK: [[V0:%.*]] = load i64, i64* [[T0]], align 16
-// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1
-// CHECK: [[V1:%.*]] = load i64, i64* [[T0]], align 8
-// CHECK: call swiftcc void @take_union_het_fpv_partial(i64 [[V0]], i64 [[V1]])
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 1
+// CHECK: [[V1:%.*]] = load float, float* [[T0]], align 8
+// CHECK: [[T0:%.*]] = getelementptr inbounds { i64, float, float }, { i64, float, float }* [[CAST]], i32 0, i32 2
+// CHECK: [[V2:%.*]] = load float, float* [[T0]], align 4
+// CHECK: call swiftcc void @take_union_het_fpv_partial(i64 [[V0]], float [[V1]], float [[V2]])
// CHECK: ret void
// CHECK: }
diff --git a/test/CodeGen/x86-vector-width.c b/test/CodeGen/x86-vector-width.c
new file mode 100644
index 0000000000..7e03fedb78
--- /dev/null
+++ b/test/CodeGen/x86-vector-width.c
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -triple i686-linux-gnu -target-cpu i686 -emit-llvm %s -o - | FileCheck %s
+
+typedef signed long long V2LLi __attribute__((vector_size(16)));
+typedef signed long long V4LLi __attribute__((vector_size(32)));
+
+V2LLi ret_128();
+V4LLi ret_256();
+void arg_128(V2LLi);
+void arg_256(V4LLi);
+
+// Make sure return type forces a min-legal-width
+V2LLi foo(void) {
+ return (V2LLi){ 0, 0 };
+}
+
+V4LLi goo(void) {
+ return (V4LLi){ 0, 0 };
+}
+
+// Make sure return type of called function forces a min-legal-width
+void hoo(void) {
+ V2LLi tmp_V2LLi;
+ tmp_V2LLi = ret_128();
+}
+
+void joo(void) {
+ V4LLi tmp_V4LLi;
+ tmp_V4LLi = ret_256();
+}
+
+// Make sure arg type of called function forces a min-legal-width
+void koo(void) {
+ V2LLi tmp_V2LLi;
+ arg_128(tmp_V2LLi);
+}
+
+void loo(void) {
+ V4LLi tmp_V4LLi;
+ arg_256(tmp_V4LLi);
+}
+
+// Make sure arg type of our function forces a min-legal-width
+void moo(V2LLi x) {
+
+}
+
+void noo(V4LLi x) {
+
+}
+
+// CHECK: {{.*}}@foo{{.*}} #0
+// CHECK: {{.*}}@goo{{.*}} #1
+// CHECK: {{.*}}@hoo{{.*}} #0
+// CHECK: {{.*}}@joo{{.*}} #1
+// CHECK: {{.*}}@koo{{.*}} #0
+// CHECK: {{.*}}@loo{{.*}} #1
+// CHECK: {{.*}}@moo{{.*}} #0
+// CHECK: {{.*}}@noo{{.*}} #1
+
+// CHECK: #0 = {{.*}}"min-legal-vector-width"="128"
+// CHECK: #1 = {{.*}}"min-legal-vector-width"="256"
diff --git a/test/CodeGen/xray-attributes-supported.cpp b/test/CodeGen/xray-attributes-supported.cpp
index 51ee4721f2..c2ee70822a 100644
--- a/test/CodeGen/xray-attributes-supported.cpp
+++ b/test/CodeGen/xray-attributes-supported.cpp
@@ -5,12 +5,36 @@
// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
// RUN: -triple mips-unknown-linux-gnu | FileCheck %s
// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa32r6-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
// RUN: -triple mipsel-unknown-linux-gnu | FileCheck %s
// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa32r6el-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
// RUN: -triple mips64-unknown-linux-gnu | FileCheck %s
// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa64r6-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
// RUN: -triple mips64el-unknown-linux-gnu | FileCheck %s
// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa64r6el-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mips64-unknown-linux-gnuabi64 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa64r6-unknown-linux-gnuabi64 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mips64el-unknown-linux-gnuabi64 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa64r6el-unknown-linux-gnuabi64 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mips64-unknown-linux-gnuabin32 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa64r6-unknown-linux-gnuabin32 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mips64el-unknown-linux-gnuabin32 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
+// RUN: -triple mipsisa64r6el-unknown-linux-gnuabin32 | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - \
// RUN: -triple powerpc64le-unknown-linux-gnu | FileCheck %s
// Make sure that the LLVM attribute for XRay-annotated functions do show up.