brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.6 KiB · 0e04191 Raw
619 lines · c
1// Test CodeGen for Security Check Overflow Builtins.2 3// RUN: %clang_cc1 -triple "i686-unknown-unknown"   -emit-llvm -x c %s -o - | FileCheck -DLONG_TYPE=i32 -DLONG_MAX=2147483647 %s4// RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck -DLONG_TYPE=i64 -DLONG_MAX=9223372036854775807 %s5// RUN: %clang_cc1 -triple "x86_64-mingw32"         -emit-llvm -x c %s -o - | FileCheck -DLONG_TYPE=i32 -DLONG_MAX=2147483647 %s6 7extern unsigned UnsignedErrorCode;8extern unsigned long UnsignedLongErrorCode;9extern unsigned long long UnsignedLongLongErrorCode;10extern int IntErrorCode;11extern long LongErrorCode;12extern long long LongLongErrorCode;13void overflowed(void);14 15unsigned test_add_overflow_uint_uint_uint(unsigned x, unsigned y) {16  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_uint_uint_uint17  // CHECK-NOT: ext18  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})19  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 020  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 121  // CHECK: store i32 [[Q]], ptr22  // CHECK: br i1 [[C]]23  unsigned r;24  if (__builtin_add_overflow(x, y, &r))25    overflowed();26  return r;27}28 29int test_add_overflow_int_int_int(int x, int y) {30  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_int_int_int31  // CHECK-NOT: ext32  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})33  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 134  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 035  // CHECK: store i32 [[Q]], ptr36  // CHECK: br i1 [[C]]37  int r;38  if (__builtin_add_overflow(x, y, &r))39    overflowed();40  return r;41}42 43int test_add_overflow_xint31_xint31_xint31(_BitInt(31) x, _BitInt(31) y) {44  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_xint31_xint31_xint31({{.+}})45  // CHECK: %loadedv = trunc i32 %{{.*}} to i3146  // CHECK-NOT: ext47  // CHECK: [[S:%.+]] = call { i31, i1 } @llvm.sadd.with.overflow.i31(i31 %{{.+}}, i31 %{{.+}})48  // CHECK-DAG: [[C:%.+]] = extractvalue { i31, i1 } [[S]], 149  // CHECK-DAG: [[Q:%.+]] = extractvalue { i31, i1 } [[S]], 050  // CHECK: [[STOREDV:%.+]] = sext i31 [[Q]] to i3251  // CHECK: store i32 [[STOREDV]], ptr52  // CHECK: br i1 [[C]]53  _BitInt(31) r;54  if (__builtin_add_overflow(x, y, &r))55    overflowed();56  return r;57}58 59unsigned test_sub_overflow_uint_uint_uint(unsigned x, unsigned y) {60  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_sub_overflow_uint_uint_uint61  // CHECK-NOT: ext62  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})63  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 064  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 165  // CHECK: store i32 [[Q]], ptr66  // CHECK: br i1 [[C]]67  unsigned r;68  if (__builtin_sub_overflow(x, y, &r))69    overflowed();70  return r;71}72 73int test_sub_overflow_int_int_int(int x, int y) {74  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_sub_overflow_int_int_int75  // CHECK-NOT: ext76  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})77  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 178  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 079  // CHECK: store i32 [[Q]], ptr80  // CHECK: br i1 [[C]]81  int r;82  if (__builtin_sub_overflow(x, y, &r))83    overflowed();84  return r;85}86 87int test_sub_overflow_xint31_xint31_xint31(_BitInt(31) x, _BitInt(31) y) {88  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_sub_overflow_xint31_xint31_xint31({{.+}})89  // CHECK: %loadedv = trunc i32 %{{.*}} to i3190  // CHECK-NOT: ext91  // CHECK: [[S:%.+]] = call { i31, i1 } @llvm.ssub.with.overflow.i31(i31 %{{.+}}, i31 %{{.+}})92  // CHECK-DAG: [[C:%.+]] = extractvalue { i31, i1 } [[S]], 193  // CHECK-DAG: [[Q:%.+]] = extractvalue { i31, i1 } [[S]], 094  // CHECK: [[STOREDV:%.+]] = sext i31 [[Q]] to i3295  // CHECK: store i32 [[STOREDV]], ptr96  // CHECK: br i1 [[C]]97  _BitInt(31) r;98  if (__builtin_sub_overflow(x, y, &r))99    overflowed();100  return r;101}102 103unsigned test_mul_overflow_uint_uint_uint(unsigned x, unsigned y) {104  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_uint_uint_uint105  // CHECK-NOT: ext106  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})107  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0108  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1109  // CHECK: store i32 [[Q]], ptr110  // CHECK: br i1 [[C]]111  unsigned r;112  if (__builtin_mul_overflow(x, y, &r))113    overflowed();114  return r;115}116 117int test_mul_overflow_uint_uint_int(unsigned x, unsigned y) {118  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_uint_uint_int119  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})120  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0121  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1122  // CHECK: [[C1:%.+]] = icmp ugt i32 [[Q]], 2147483647123  // CHECK: [[C2:%.+]] = or i1 [[C]], [[C1]]124  // CHECK: store i32 [[Q]], ptr125  // CHECK: br i1 [[C2]]126  int r;127  if (__builtin_mul_overflow(x, y, &r))128    overflowed();129  return r;130}131 132int test_mul_overflow_uint_uint_int_volatile(unsigned x, unsigned y) {133  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_uint_uint_int_volatile134  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})135  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0136  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1137  // CHECK: [[C1:%.+]] = icmp ugt i32 [[Q]], 2147483647138  // CHECK: [[C2:%.+]] = or i1 [[C]], [[C1]]139  // CHECK: store volatile i32 [[Q]], ptr140  // CHECK: br i1 [[C2]]141  volatile int r;142  if (__builtin_mul_overflow(x, y, &r))143    overflowed();144  return r;145}146 147long test_mul_overflow_ulong_ulong_long(unsigned long x, unsigned long y) {148  // CHECK-LABEL: @test_mul_overflow_ulong_ulong_long149  // CHECK: [[S:%.+]] =  call { [[LONG_TYPE]], i1 } @llvm.umul.with.overflow.[[LONG_TYPE]]([[LONG_TYPE]] %{{.+}}, [[LONG_TYPE]] %{{.+}})150  // CHECK-DAG: [[Q:%.+]] = extractvalue { [[LONG_TYPE]], i1 } [[S]], 0151  // CHECK-DAG: [[C:%.+]] = extractvalue { [[LONG_TYPE]], i1 } [[S]], 1152  // CHECK: [[C1:%.+]] = icmp ugt [[LONG_TYPE]] [[Q]], [[LONG_MAX]]153  // CHECK: [[C2:%.+]] = or i1 [[C]], [[C1]]154  // LONG64: store [[LONG_TYPE]] [[Q]], ptr155  // LONG64: br i1 [[C2]]156  long r;157  if (__builtin_mul_overflow(x, y, &r))158    overflowed();159  return r;160}161 162int test_mul_overflow_int_int_int(int x, int y) {163  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_int_int_int164  // CHECK-NOT: ext165  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})166  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1167  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0168  // CHECK: store i32 [[Q]], ptr169  // CHECK: br i1 [[C]]170  int r;171  if (__builtin_mul_overflow(x, y, &r))172    overflowed();173  return r;174}175 176int test_mul_overflow_xint31_xint31_xint31(_BitInt(31) x, _BitInt(31) y) {177  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_xint31_xint31_xint31({{.+}})178  // CHECK: %loadedv = trunc i32 %{{.*}} to i31179  // CHECK-NOT: ext180  // CHECK: [[S:%.+]] = call { i31, i1 } @llvm.smul.with.overflow.i31(i31 %{{.+}}, i31 %{{.+}})181  // CHECK-DAG: [[C:%.+]] = extractvalue { i31, i1 } [[S]], 1182  // CHECK-DAG: [[Q:%.+]] = extractvalue { i31, i1 } [[S]], 0183  // CHECK: [[STOREDV:%.+]] = sext i31 [[Q]] to i32184  // CHECK: store i32 [[STOREDV]], ptr185  // CHECK: br i1 [[C]]186  _BitInt(31) r;187  if (__builtin_mul_overflow(x, y, &r))188    overflowed();189  return r;190}191 192int test_mul_overflow_xint127_xint127_xint127(_BitInt(127) x, _BitInt(127) y) {193  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_xint127_xint127_xint127({{.+}})194  // CHECK: %loadedv = trunc i128 %{{.*}} to i127195  // CHECK-NOT: ext196  // CHECK: [[S:%.+]] = call { i127, i1 } @llvm.smul.with.overflow.i127(i127 %{{.+}}, i127 %{{.+}})197  // CHECK-DAG: [[C:%.+]] = extractvalue { i127, i1 } [[S]], 1198  // CHECK-DAG: [[Q:%.+]] = extractvalue { i127, i1 } [[S]], 0199  // CHECK: [[STOREDV:%.+]] = sext i127 [[Q]] to i128200  // CHECK: store i128 [[STOREDV]], ptr201  // CHECK: br i1 [[C]]202  _BitInt(127) r;203  if (__builtin_mul_overflow(x, y, &r))204    overflowed();205  return r;206}207 208int test_mul_overflow_xint128_xint128_xint128(_BitInt(128) x, _BitInt(128) y) {209  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_xint128_xint128_xint128({{.+}})210  // CHECK-NOT: ext211  // CHECK: [[S:%.+]] = call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %{{.+}}, i128 %{{.+}})212  // CHECK-DAG: [[C:%.+]] = extractvalue { i128, i1 } [[S]], 1213  // CHECK-DAG: [[Q:%.+]] = extractvalue { i128, i1 } [[S]], 0214  // CHECK: store i128 [[Q]], ptr215  // CHECK: br i1 [[C]]216  _BitInt(128) r;217  if (__builtin_mul_overflow(x, y, &r))218    overflowed();219  return r;220}221 222int test_add_overflow_uint_int_int(unsigned x, int y) {223  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_uint_int_int224  // CHECK: [[XE:%.+]] = zext i32 %{{.+}} to i33225  // CHECK: [[YE:%.+]] = sext i32 %{{.+}} to i33226  // CHECK: [[S:%.+]] = call { i33, i1 } @llvm.sadd.with.overflow.i33(i33 [[XE]], i33 [[YE]])227  // CHECK-DAG: [[Q:%.+]] = extractvalue { i33, i1 } [[S]], 0228  // CHECK-DAG: [[C1:%.+]] = extractvalue { i33, i1 } [[S]], 1229  // CHECK: [[QT:%.+]] = trunc i33 [[Q]] to i32230  // CHECK: [[QTE:%.+]] = sext i32 [[QT]] to i33231  // CHECK: [[C2:%.+]] = icmp ne i33 [[Q]], [[QTE]]232  // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]233  // CHECK: store i32 [[QT]], ptr234  // CHECK: br i1 [[C3]]235  int r;236  if (__builtin_add_overflow(x, y, &r))237    overflowed();238  return r;239}240 241_Bool test_add_overflow_uint_uint_bool(unsigned x, unsigned y) {242  // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_uint_uint_bool243  // CHECK-NOT: ext244  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})245  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0246  // CHECK-DAG: [[C1:%.+]] = extractvalue { i32, i1 } [[S]], 1247  // CHECK: [[QT:%.+]] = trunc i32 [[Q]] to i1248  // CHECK: [[QTE:%.+]] = zext i1 [[QT]] to i32249  // CHECK: [[C2:%.+]] = icmp ne i32 [[Q]], [[QTE]]250  // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]251  // CHECK: [[QT2:%.+]] = zext i1 [[QT]] to i8252  // CHECK: store i8 [[QT2]], ptr253  // CHECK: br i1 [[C3]]254  _Bool r;255  if (__builtin_add_overflow(x, y, &r))256    overflowed();257  return r;258}259 260unsigned test_add_overflow_bool_bool_uint(_Bool x, _Bool y) {261  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_bool_bool_uint262  // CHECK: [[XE:%.+]] = zext i1 %{{.+}} to i32263  // CHECK: [[YE:%.+]] = zext i1 %{{.+}} to i32264  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[XE]], i32 [[YE]])265  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0266  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1267  // CHECK: store i32 [[Q]], ptr268  // CHECK: br i1 [[C]]269  unsigned r;270  if (__builtin_add_overflow(x, y, &r))271    overflowed();272  return r;273}274 275_Bool test_add_overflow_bool_bool_bool(_Bool x, _Bool y) {276  // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_bool_bool_bool277  // CHECK: [[S:%.+]] = call { i1, i1 } @llvm.uadd.with.overflow.i1(i1 %{{.+}}, i1 %{{.+}})278  // CHECK-DAG: [[Q:%.+]] = extractvalue { i1, i1 } [[S]], 0279  // CHECK-DAG: [[C:%.+]] = extractvalue { i1, i1 } [[S]], 1280  // CHECK: [[QT2:%.+]] = zext i1 [[Q]] to i8281  // CHECK: store i8 [[QT2]], ptr282  // CHECK: br i1 [[C]]283  _Bool r;284  if (__builtin_add_overflow(x, y, &r))285    overflowed();286  return r;287}288 289int test_add_overflow_volatile(int x, int y) {290  // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_volatile291  // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})292  // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0293  // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1294  // CHECK: store volatile i32 [[Q]], ptr295  // CHECK: br i1 [[C]]296  volatile int result;297  if (__builtin_add_overflow(x, y, &result))298    overflowed();299  return result;300}301 302unsigned test_uadd_overflow(unsigned x, unsigned y) {303// CHECK: @test_uadd_overflow304// CHECK: %{{.+}} = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})305  unsigned result;306  if (__builtin_uadd_overflow(x, y, &result))307    return UnsignedErrorCode;308  return result;309}310 311unsigned long test_uaddl_overflow(unsigned long x, unsigned long y) {312// CHECK: @test_uaddl_overflow([[UL:i32|i64]] noundef %x313// CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})314  unsigned long result;315  if (__builtin_uaddl_overflow(x, y, &result))316    return UnsignedLongErrorCode;317  return result;318}319 320unsigned long long test_uaddll_overflow(unsigned long long x, unsigned long long y) {321// CHECK: @test_uaddll_overflow322// CHECK: %{{.+}} = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})323  unsigned long long result;324  if (__builtin_uaddll_overflow(x, y, &result))325    return UnsignedLongLongErrorCode;326  return result;327}328 329unsigned test_usub_overflow(unsigned x, unsigned y) {330// CHECK: @test_usub_overflow331// CHECK: %{{.+}} = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})332  unsigned result;333  if (__builtin_usub_overflow(x, y, &result))334    return UnsignedErrorCode;335  return result;336}337 338unsigned long test_usubl_overflow(unsigned long x, unsigned long y) {339// CHECK: @test_usubl_overflow([[UL:i32|i64]] noundef %x340// CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})341  unsigned long result;342  if (__builtin_usubl_overflow(x, y, &result))343    return UnsignedLongErrorCode;344  return result;345}346 347unsigned long long test_usubll_overflow(unsigned long long x, unsigned long long y) {348// CHECK: @test_usubll_overflow349// CHECK: %{{.+}} = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})350  unsigned long long result;351  if (__builtin_usubll_overflow(x, y, &result))352    return UnsignedLongLongErrorCode;353  return result;354}355 356unsigned test_umul_overflow(unsigned x, unsigned y) {357// CHECK: @test_umul_overflow358// CHECK: %{{.+}} = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})359  unsigned result;360  if (__builtin_umul_overflow(x, y, &result))361    return UnsignedErrorCode;362  return result;363}364 365unsigned long test_umull_overflow(unsigned long x, unsigned long y) {366// CHECK: @test_umull_overflow([[UL:i32|i64]] noundef %x367// CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.umul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})368  unsigned long result;369  if (__builtin_umull_overflow(x, y, &result))370    return UnsignedLongErrorCode;371  return result;372}373 374unsigned long long test_umulll_overflow(unsigned long long x, unsigned long long y) {375// CHECK: @test_umulll_overflow376// CHECK: %{{.+}} = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})377  unsigned long long result;378  if (__builtin_umulll_overflow(x, y, &result))379    return UnsignedLongLongErrorCode;380  return result;381}382 383int test_sadd_overflow(int x, int y) {384// CHECK: @test_sadd_overflow385// CHECK: %{{.+}} = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})386  int result;387  if (__builtin_sadd_overflow(x, y, &result))388    return IntErrorCode;389  return result;390}391 392long test_saddl_overflow(long x, long y) {393// CHECK: @test_saddl_overflow([[UL:i32|i64]] noundef %x394// CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.sadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})395  long result;396  if (__builtin_saddl_overflow(x, y, &result))397    return LongErrorCode;398  return result;399}400 401long long test_saddll_overflow(long long x, long long y) {402// CHECK: @test_saddll_overflow403// CHECK: %{{.+}} = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})404  long long result;405  if (__builtin_saddll_overflow(x, y, &result))406    return LongLongErrorCode;407  return result;408}409 410int test_ssub_overflow(int x, int y) {411// CHECK: @test_ssub_overflow412// CHECK: %{{.+}} = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})413  int result;414  if (__builtin_ssub_overflow(x, y, &result))415    return IntErrorCode;416  return result;417}418 419long test_ssubl_overflow(long x, long y) {420// CHECK: @test_ssubl_overflow([[UL:i32|i64]] noundef %x421// CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.ssub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})422  long result;423  if (__builtin_ssubl_overflow(x, y, &result))424    return LongErrorCode;425  return result;426}427 428long long test_ssubll_overflow(long long x, long long y) {429// CHECK: @test_ssubll_overflow430// CHECK: %{{.+}} = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})431  long long result;432  if (__builtin_ssubll_overflow(x, y, &result))433    return LongLongErrorCode;434  return result;435}436 437int test_smul_overflow(int x, int y) {438// CHECK: @test_smul_overflow439// CHECK: %{{.+}} = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})440  int result;441  if (__builtin_smul_overflow(x, y, &result))442    return IntErrorCode;443  return result;444}445 446long test_smull_overflow(long x, long y) {447// CHECK: @test_smull_overflow([[UL:i32|i64]] noundef %x448// CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.smul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})449  long result;450  if (__builtin_smull_overflow(x, y, &result))451    return LongErrorCode;452  return result;453}454 455long long test_smulll_overflow(long long x, long long y) {456// CHECK: @test_smulll_overflow457// CHECK: %{{.+}} = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})458  long long result;459  if (__builtin_smulll_overflow(x, y, &result))460    return LongLongErrorCode;461  return result;462}463 464int test_mixed_sign_mul_overflow_sext_signed_op(int x, unsigned long long y) {465// CHECK: @test_mixed_sign_mul_overflow_sext_signed_op466// CHECK: [[SignedOp:%.*]] = sext i32 %0 to i64467// CHECK: [[IsNeg:%.*]] = icmp slt i64 [[SignedOp]], 0468  int result;469  if (__builtin_mul_overflow(x, y, &result))470    return LongErrorCode;471  return result;472}473 474int test_mixed_sign_mul_overflow_zext_unsigned_op(long long x, unsigned y) {475// CHECK: @test_mixed_sign_mul_overflow_zext_unsigned_op476// CHECK: [[UnsignedOp:%.*]] = zext i32 %1 to i64477// CHECK: [[IsNeg:%.*]] = icmp slt i64 %0, 0478// CHECK: @llvm.umul.with.overflow.i64({{.*}}, i64 [[UnsignedOp]])479  int result;480  if (__builtin_mul_overflow(x, y, &result))481    return LongErrorCode;482  return result;483}484 485int test_mixed_sign_mull_overflow(int x, unsigned y) {486// CHECK: @test_mixed_sign_mull_overflow487// CHECK:       [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0488// CHECK-NEXT:  [[Signed:%.*]] = sub i32 0, [[Op1]]489// CHECK-NEXT:  [[AbsSigned:%.*]] = select i1 [[IsNeg]], i32 [[Signed]], i32 [[Op1]]490// CHECK-NEXT:  call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[AbsSigned]], i32 %{{.*}})491// CHECK-NEXT:  [[UnsignedOFlow:%.*]] = extractvalue { i32, i1 } %{{.*}}, 1492// CHECK-NEXT:  [[UnsignedResult:%.*]] = extractvalue { i32, i1 } %{{.*}}, 0493// CHECK-NEXT:  [[IsNegZext:%.*]] = zext i1 [[IsNeg]] to i32494// CHECK-NEXT:  [[MaxResult:%.*]] = add i32 2147483647, [[IsNegZext]]495// CHECK-NEXT:  [[SignedOFlow:%.*]] = icmp ugt i32 [[UnsignedResult]], [[MaxResult]]496// CHECK-NEXT:  [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[SignedOFlow]]497// CHECK-NEXT:  [[NegativeResult:%.*]] = sub i32 0, [[UnsignedResult]]498// CHECK-NEXT:  [[Result:%.*]] = select i1 [[IsNeg]], i32 [[NegativeResult]], i32 [[UnsignedResult]]499// CHECK-NEXT:  store i32 [[Result]], ptr %{{.*}}, align 4500// CHECK:       br i1 [[OFlow]]501 502  int result;503  if (__builtin_mul_overflow(x, y, &result))504    return LongErrorCode;505  return result;506}507 508int test_mixed_sign_mull_overflow_unsigned(int x, unsigned y) {509// CHECK: @test_mixed_sign_mull_overflow_unsigned510// CHECK:       [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0511// CHECK-NEXT:  [[Signed:%.*]] = sub i32 0, [[Op1]]512// CHECK-NEXT:  [[AbsSigned:%.*]] = select i1 [[IsNeg]], i32 [[Signed]], i32 [[Op1]]513// CHECK-NEXT:  call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[AbsSigned]], i32 %{{.*}})514// CHECK-NEXT:  [[UnsignedOFlow:%.*]] = extractvalue { i32, i1 } %{{.*}}, 1515// CHECK-NEXT:  [[UnsignedResult:%.*]] = extractvalue { i32, i1 } %{{.*}}, 0516// CHECK-NEXT:  [[NotNull:%.*]] = icmp ne i32 [[UnsignedResult]], 0517// CHECK-NEXT:  [[Underflow:%.*]] = and i1 [[IsNeg]], [[NotNull]]518// CHECK-NEXT:  [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[Underflow]]519// CHECK-NEXT:  [[NegatedResult:%.*]] = sub i32 0, [[UnsignedResult]]520// CHECK-NEXT:  [[Result:%.*]] = select i1 [[IsNeg]], i32 [[NegatedResult]], i32 [[UnsignedResult]]521// CHECK-NEXT:  store i32 [[Result]], ptr %{{.*}}, align 4522// CHECK:       br i1 [[OFlow]]523 524  unsigned result;525  if (__builtin_mul_overflow(x, y, &result))526    return LongErrorCode;527  return result;528}529 530int test_mixed_sign_mull_overflow_swapped(int x, unsigned y) {531// CHECK: @test_mixed_sign_mull_overflow_swapped532// CHECK:  call { i32, i1 } @llvm.umul.with.overflow.i32533// CHECK:  add i32 2147483647534  int result;535  if (__builtin_mul_overflow(y, x, &result))536    return LongErrorCode;537  return result;538}539 540long long test_mixed_sign_mulll_overflow(long long x, unsigned long long y) {541// CHECK: @test_mixed_sign_mulll_overflow542// CHECK:  call { i64, i1 } @llvm.umul.with.overflow.i64543// CHECK:  add i64 92233720368547544  long long result;545  if (__builtin_mul_overflow(x, y, &result))546    return LongLongErrorCode;547  return result;548}549 550long long test_mixed_sign_mulll_overflow_swapped(long long x, unsigned long long y) {551// CHECK: @test_mixed_sign_mulll_overflow_swapped552// CHECK:  call { i64, i1 } @llvm.umul.with.overflow.i64553// CHECK:  add i64 92233720368547554  long long result;555  if (__builtin_mul_overflow(y, x, &result))556    return LongLongErrorCode;557  return result;558}559 560long long test_mixed_sign_mulll_overflow_trunc_signed(long long x, unsigned long long y) {561// CHECK: @test_mixed_sign_mulll_overflow_trunc_signed562// CHECK:  call { i64, i1 } @llvm.umul.with.overflow.i64563// CHECK:  add i64 2147483647564// CHECK:  trunc565// CHECK:  store566  int result;567  if (__builtin_mul_overflow(y, x, &result))568    return LongLongErrorCode;569  return result;570}571 572long long test_mixed_sign_mulll_overflow_trunc_unsigned(long long x, unsigned long long y) {573// CHECK: @test_mixed_sign_mulll_overflow_trunc_unsigned574// CHECK:       call { i64, i1 } @llvm.umul.with.overflow.i64575// CHECK:       [[NON_ZERO:%.*]] = icmp ne i64 [[UNSIGNED_RESULT:%.*]], 0576// CHECK-NEXT:  [[UNDERFLOW:%.*]] = and i1 {{.*}}, [[NON_ZERO]]577// CHECK-NEXT:  [[OVERFLOW_PRE_TRUNC:%.*]] = or i1 {{.*}}, [[UNDERFLOW]]578// CHECK-NEXT:  [[TRUNC_OVERFLOW:%.*]] = icmp ugt i64 [[UNSIGNED_RESULT]], 4294967295579// CHECK-NEXT:  [[OVERFLOW:%.*]] = or i1 [[OVERFLOW_PRE_TRUNC]], [[TRUNC_OVERFLOW]]580// CHECK-NEXT:  [[NEGATED:%.*]] = sub i64 0, [[UNSIGNED_RESULT]]581// CHECK-NEXT:  [[RESULT:%.*]] = select i1 {{.*}}, i64 [[NEGATED]], i64 [[UNSIGNED_RESULT]]582// CHECK-NEXT:  trunc i64 [[RESULT]] to i32583// CHECK-NEXT:  store584  unsigned result;585  if (__builtin_mul_overflow(y, x, &result))586    return LongLongErrorCode;587  return result;588}589 590long long test_mixed_sign_mul_overflow_extend_signed(int x, unsigned y) {591// CHECK: @test_mixed_sign_mul_overflow_extend_signed592// CHECK:  call { i64, i1 } @llvm.smul.with.overflow.i64593  long long result;594  if (__builtin_mul_overflow(y, x, &result))595    return LongLongErrorCode;596  return result;597}598 599long long test_mixed_sign_mul_overflow_extend_unsigned(int x, unsigned y) {600// CHECK: @test_mixed_sign_mul_overflow_extend_unsigned601// CHECK:  call { i65, i1 } @llvm.smul.with.overflow.i65602  unsigned long long result;603  if (__builtin_mul_overflow(y, x, &result))604    return LongLongErrorCode;605  return result;606}607 608_BitInt(65) test_mixed_sign_mul_overflow_bitint(unsigned _BitInt(65) y, _BitInt(119) a) {609// CHECK: call { i119, i1 } @llvm.umul.with.overflow.i119610// CHECK: select i1 %{{.*}}, i119 %{{.*}}, i119 %{{.*}}611// CHECK: trunc i119612// CHECK: zext i65613// CHECK: store614  unsigned _BitInt(65) result;615  if (__builtin_mul_overflow(a, y, &result))616    return LongLongErrorCode;617  return result;618}619