CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
391 lines
20 KiB
C++
391 lines
20 KiB
C++
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
|
|
// RUN: FileCheck %s --check-prefix=CIR --input-file=%t.cir
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
|
|
// RUN: FileCheck %s --check-prefix=LLVM --input-file=%t-cir.ll
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
|
|
// RUN: FileCheck %s --check-prefix=LLVM --input-file=%t.ll
|
|
|
|
bool test_add_overflow_uint_uint_uint(unsigned x, unsigned y, unsigned *res) {
|
|
return __builtin_add_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z32test_add_overflow_uint_uint_uintjjPj
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#LHS]], %[[#RHS]] : !u32i -> !u32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u32i, !cir.ptr<!u32i>
|
|
// CIR: }
|
|
|
|
// LLVM: define{{.*}} i1 @_Z32test_add_overflow_uint_uint_uintjjPj(i32{{.*}}, i32{{.*}}, ptr{{.*}})
|
|
// LLVM: call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
|
|
|
|
|
|
bool test_add_overflow_int_int_int(int x, int y, int *res) {
|
|
return __builtin_add_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z29test_add_overflow_int_int_intiiPi
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#LHS]], %[[#RHS]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_add_overflow_xint31_xint31_xint31(_BitInt(31) x, _BitInt(31) y, _BitInt(31) *res) {
|
|
return __builtin_add_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z38test_add_overflow_xint31_xint31_xint31DB31_S_PS_
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.int<s, 31, bitint>>, !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.int<s, 31, bitint>>, !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!cir.int<s, 31, bitint>>>, !cir.ptr<!cir.int<s, 31, bitint>>
|
|
// CIR: %[[RES:.+]], %{{.+}} = cir.add.overflow %{{.+}}, %{{.+}} : !cir.int<s, 31> -> !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !cir.int<s, 31, bitint>, !cir.ptr<!cir.int<s, 31, bitint>>
|
|
// CIR: }
|
|
|
|
bool test_sub_overflow_uint_uint_uint(unsigned x, unsigned y, unsigned *res) {
|
|
return __builtin_sub_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z32test_sub_overflow_uint_uint_uintjjPj
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#LHS]], %[[#RHS]] : !u32i -> !u32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u32i, !cir.ptr<!u32i>
|
|
// CIR: }
|
|
|
|
bool test_sub_overflow_int_int_int(int x, int y, int *res) {
|
|
return __builtin_sub_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z29test_sub_overflow_int_int_intiiPi
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#LHS]], %[[#RHS]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_sub_overflow_xint31_xint31_xint31(_BitInt(31) x, _BitInt(31) y, _BitInt(31) *res) {
|
|
return __builtin_sub_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z38test_sub_overflow_xint31_xint31_xint31DB31_S_PS_
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.int<s, 31, bitint>>, !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.int<s, 31, bitint>>, !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!cir.int<s, 31, bitint>>>, !cir.ptr<!cir.int<s, 31, bitint>>
|
|
// CIR: %[[RES:.+]], %{{.+}} = cir.sub.overflow %{{.+}}, %{{.+}} : !cir.int<s, 31> -> !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !cir.int<s, 31, bitint>, !cir.ptr<!cir.int<s, 31, bitint>>
|
|
// CIR: }
|
|
|
|
bool test_mul_overflow_uint_uint_uint(unsigned x, unsigned y, unsigned *res) {
|
|
return __builtin_mul_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z32test_mul_overflow_uint_uint_uintjjPj
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#LHS]], %[[#RHS]] : !u32i -> !u32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u32i, !cir.ptr<!u32i>
|
|
// CIR: }
|
|
|
|
bool test_mul_overflow_int_int_int(int x, int y, int *res) {
|
|
return __builtin_mul_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z29test_mul_overflow_int_int_intiiPi
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#LHS]], %[[#RHS]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_mul_overflow_xint31_xint31_xint31(_BitInt(31) x, _BitInt(31) y, _BitInt(31) *res) {
|
|
return __builtin_mul_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z38test_mul_overflow_xint31_xint31_xint31DB31_S_PS_
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.int<s, 31, bitint>>, !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.int<s, 31, bitint>>, !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!cir.int<s, 31, bitint>>>, !cir.ptr<!cir.int<s, 31, bitint>>
|
|
// CIR: %[[RES:.+]], %{{.+}} = cir.mul.overflow %{{.+}}, %{{.+}} : !cir.int<s, 31> -> !cir.int<s, 31, bitint>
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !cir.int<s, 31, bitint>, !cir.ptr<!cir.int<s, 31, bitint>>
|
|
// CIR: }
|
|
|
|
bool test_mul_overflow_ulong_ulong_long(unsigned long x, unsigned long y, unsigned long *res) {
|
|
return __builtin_mul_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z34test_mul_overflow_ulong_ulong_longmmPm
|
|
// CIR: %[[#LHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RHS:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#LHS]], %[[#RHS]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_add_overflow_uint_int_int(unsigned x, int y, int *res) {
|
|
return __builtin_add_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z30test_add_overflow_uint_int_intjiPi
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[#PROM_X:]] = cir.cast integral %[[#X]] : !u32i -> !cir.int<s, 33>
|
|
// CIR-NEXT: %[[#PROM_Y:]] = cir.cast integral %[[#Y]] : !s32i -> !cir.int<s, 33>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#PROM_X]], %[[#PROM_Y]] : !cir.int<s, 33> -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_add_overflow_volatile(int x, int y, volatile int *res) {
|
|
return __builtin_add_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z26test_add_overflow_volatileiiPVi
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store volatile{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_uadd_overflow(unsigned x, unsigned y, unsigned *res) {
|
|
return __builtin_uadd_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z18test_uadd_overflowjjPj
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !u32i -> !u32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u32i, !cir.ptr<!u32i>
|
|
// CIR: }
|
|
|
|
bool test_uaddl_overflow(unsigned long x, unsigned long y, unsigned long *res) {
|
|
return __builtin_uaddl_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z19test_uaddl_overflowmmPm
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_uaddll_overflow(unsigned long long x, unsigned long long y, unsigned long long *res) {
|
|
return __builtin_uaddll_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z20test_uaddll_overflowyyPy
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_usub_overflow(unsigned x, unsigned y, unsigned *res) {
|
|
return __builtin_usub_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z18test_usub_overflowjjPj
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#X]], %[[#Y]] : !u32i -> !u32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u32i, !cir.ptr<!u32i>
|
|
// CIR: }
|
|
|
|
bool test_usubl_overflow(unsigned long x, unsigned long y, unsigned long *res) {
|
|
return __builtin_usubl_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z19test_usubl_overflowmmPm
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#X]], %[[#Y]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_usubll_overflow(unsigned long long x, unsigned long long y, unsigned long long *res) {
|
|
return __builtin_usubll_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z20test_usubll_overflowyyPy
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#X]], %[[#Y]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_umul_overflow(unsigned x, unsigned y, unsigned *res) {
|
|
return __builtin_umul_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z18test_umul_overflowjjPj
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#X]], %[[#Y]] : !u32i -> !u32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u32i, !cir.ptr<!u32i>
|
|
// CIR: }
|
|
|
|
bool test_umull_overflow(unsigned long x, unsigned long y, unsigned long *res) {
|
|
return __builtin_umull_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z19test_umull_overflowmmPm
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#X]], %[[#Y]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_umulll_overflow(unsigned long long x, unsigned long long y, unsigned long long *res) {
|
|
return __builtin_umulll_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z20test_umulll_overflowyyPy
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u64i>, !u64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#X]], %[[#Y]] : !u64i -> !u64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !u64i, !cir.ptr<!u64i>
|
|
// CIR: }
|
|
|
|
bool test_sadd_overflow(int x, int y, int *res) {
|
|
return __builtin_sadd_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z18test_sadd_overflowiiPi
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_saddl_overflow(long x, long y, long *res) {
|
|
return __builtin_saddl_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z19test_saddl_overflowllPl
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !s64i -> !s64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s64i, !cir.ptr<!s64i>
|
|
// CIR: }
|
|
|
|
bool test_saddll_overflow(long long x, long long y, long long *res) {
|
|
return __builtin_saddll_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z20test_saddll_overflowxxPx
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.add.overflow %[[#X]], %[[#Y]] : !s64i -> !s64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s64i, !cir.ptr<!s64i>
|
|
// CIR: }
|
|
|
|
bool test_ssub_overflow(int x, int y, int *res) {
|
|
return __builtin_ssub_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z18test_ssub_overflowiiPi
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#X]], %[[#Y]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_ssubl_overflow(long x, long y, long *res) {
|
|
return __builtin_ssubl_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z19test_ssubl_overflowllPl
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#X]], %[[#Y]] : !s64i -> !s64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s64i, !cir.ptr<!s64i>
|
|
// CIR: }
|
|
|
|
bool test_ssubll_overflow(long long x, long long y, long long *res) {
|
|
return __builtin_ssubll_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z20test_ssubll_overflowxxPx
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.sub.overflow %[[#X]], %[[#Y]] : !s64i -> !s64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s64i, !cir.ptr<!s64i>
|
|
// CIR: }
|
|
|
|
bool test_smul_overflow(int x, int y, int *res) {
|
|
return __builtin_smul_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z18test_smul_overflowiiPi
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s32i>, !s32i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#X]], %[[#Y]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: }
|
|
|
|
bool test_smull_overflow(long x, long y, long *res) {
|
|
return __builtin_smull_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z19test_smull_overflowllPl
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#X]], %[[#Y]] : !s64i -> !s64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s64i, !cir.ptr<!s64i>
|
|
// CIR: }
|
|
|
|
bool test_smulll_overflow(long long x, long long y, long long *res) {
|
|
return __builtin_smulll_overflow(x, y, res);
|
|
}
|
|
|
|
// CIR: cir.func {{.*}} @_Z20test_smulll_overflowxxPx
|
|
// CIR: %[[#X:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#Y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!s64i>, !s64i
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
|
|
// CIR-NEXT: %[[RES:.+]], %{{.+}} = cir.mul.overflow %[[#X]], %[[#Y]] : !s64i -> !s64i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s64i, !cir.ptr<!s64i>
|
|
// CIR: }
|
|
|
|
bool test_bool_math_overflow(bool x, bool y, int *res) {
|
|
return __builtin_add_overflow(x, y, res);
|
|
// CIR-LABEL: test_bool_math_overflow
|
|
// CIR: %[[LOAD_X:.*]] = cir.load align(1) %{{.*}} : !cir.ptr<!cir.bool>, !cir.bool
|
|
// CIR-NEXT: %[[LOAD_Y:.*]] = cir.load align(1) %{{.*}} : !cir.ptr<!cir.bool>, !cir.bool
|
|
// CIR-NEXT: %[[#RES_PTR:]] = cir.load align(8) %{{.*}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
|
|
// CIR-NEXT: %[[X_CAST:.*]] = cir.cast bool_to_int %[[LOAD_X]] : !cir.bool -> !s32i
|
|
// CIR-NEXT: %[[Y_CAST:.*]] = cir.cast bool_to_int %[[LOAD_Y]] : !cir.bool -> !s32i
|
|
// CIR-NEXT: %[[RES:.*]], %{{.*}} = cir.add.overflow %[[X_CAST]], %[[Y_CAST]] : !s32i -> !s32i
|
|
// CIR-NEXT: cir.store{{.*}} %[[RES]], %[[#RES_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
|
|
// LLVM-LABEL: test_bool_math_overflow
|
|
// LLVM: %[[X_CAST:.*]] = zext i1 %{{.*}} to i32
|
|
// LLVM: %[[Y_CAST:.*]] = zext i1 %{{.*}} to i32
|
|
// LLVM: call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %[[X_CAST]], i32 %[[Y_CAST]])
|
|
}
|
|
|