-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IR] Avoid creating icmp/fcmp constant expressions #92885
Conversation
Do not create icmp/fcmp constant expressions in IRBuilder etc anymore, i.e. treat them as "undesirable". This is in preparation for removing them entirely. Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
@llvm/pr-subscribers-backend-amdgpu @llvm/pr-subscribers-llvm-analysis Author: Nikita Popov (nikic) ChangesDo not create icmp/fcmp constant expressions in IRBuilder etc anymore, i.e. treat them as "undesirable". This is in preparation for removing them entirely. Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179 Patch is 92.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92885.diff 40 Files Affected:
diff --git a/clang/test/Analysis/builtin_signbit.cpp b/clang/test/Analysis/builtin_signbit.cpp
index 57e6816ce2802..be10f0950f69b 100644
--- a/clang/test/Analysis/builtin_signbit.cpp
+++ b/clang/test/Analysis/builtin_signbit.cpp
@@ -84,28 +84,30 @@ long double ld = -1.0L;
// CHECK-LE-LABEL: define dso_local void @_Z12test_signbitv(
// CHECK-LE-SAME: ) #[[ATTR0:[0-9]+]] {
// CHECK-LE-NEXT: entry:
-// CHECK-LE-NEXT: [[FROMBOOL:%.*]] = zext i1 icmp slt (i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), i64 0) to i8
+// CHECK-LE-NEXT: [[TMP0:%.*]] = icmp slt i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), 0
+// CHECK-LE-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP0]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL]], ptr @b, align 1
-// CHECK-LE-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr @ld, align 16
-// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast ppc_fp128 [[TMP0]] to i128
-// CHECK-LE-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP1]] to i64
-// CHECK-LE-NEXT: [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 0
-// CHECK-LE-NEXT: [[FROMBOOL1:%.*]] = zext i1 [[TMP3]] to i8
+// CHECK-LE-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr @ld, align 16
+// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128
+// CHECK-LE-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i64
+// CHECK-LE-NEXT: [[TMP4:%.*]] = icmp slt i64 [[TMP3]], 0
+// CHECK-LE-NEXT: [[FROMBOOL1:%.*]] = zext i1 [[TMP4]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL1]], ptr @b, align 1
// CHECK-LE-NEXT: store i8 0, ptr @b, align 1
-// CHECK-LE-NEXT: [[TMP4:%.*]] = load double, ptr @d, align 8
-// CHECK-LE-NEXT: [[CONV:%.*]] = fptrunc double [[TMP4]] to float
-// CHECK-LE-NEXT: [[TMP5:%.*]] = bitcast float [[CONV]] to i32
-// CHECK-LE-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP5]], 0
-// CHECK-LE-NEXT: [[FROMBOOL2:%.*]] = zext i1 [[TMP6]] to i8
+// CHECK-LE-NEXT: [[TMP5:%.*]] = load double, ptr @d, align 8
+// CHECK-LE-NEXT: [[CONV:%.*]] = fptrunc double [[TMP5]] to float
+// CHECK-LE-NEXT: [[TMP6:%.*]] = bitcast float [[CONV]] to i32
+// CHECK-LE-NEXT: [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 0
+// CHECK-LE-NEXT: [[FROMBOOL2:%.*]] = zext i1 [[TMP7]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL2]], ptr @b, align 1
-// CHECK-LE-NEXT: [[FROMBOOL3:%.*]] = zext i1 icmp slt (i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), i64 0) to i8
+// CHECK-LE-NEXT: [[TMP8:%.*]] = icmp slt i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), 0
+// CHECK-LE-NEXT: [[FROMBOOL3:%.*]] = zext i1 [[TMP8]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL3]], ptr @b, align 1
-// CHECK-LE-NEXT: [[TMP7:%.*]] = load ppc_fp128, ptr @ld, align 16
-// CHECK-LE-NEXT: [[TMP8:%.*]] = bitcast ppc_fp128 [[TMP7]] to i128
-// CHECK-LE-NEXT: [[TMP9:%.*]] = trunc i128 [[TMP8]] to i64
-// CHECK-LE-NEXT: [[TMP10:%.*]] = icmp slt i64 [[TMP9]], 0
-// CHECK-LE-NEXT: [[FROMBOOL4:%.*]] = zext i1 [[TMP10]] to i8
+// CHECK-LE-NEXT: [[TMP9:%.*]] = load ppc_fp128, ptr @ld, align 16
+// CHECK-LE-NEXT: [[TMP10:%.*]] = bitcast ppc_fp128 [[TMP9]] to i128
+// CHECK-LE-NEXT: [[TMP11:%.*]] = trunc i128 [[TMP10]] to i64
+// CHECK-LE-NEXT: [[TMP12:%.*]] = icmp slt i64 [[TMP11]], 0
+// CHECK-LE-NEXT: [[FROMBOOL4:%.*]] = zext i1 [[TMP12]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL4]], ptr @b, align 1
// CHECK-LE-NEXT: ret void
//
diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
index 015102940890a..e93dbcb9f647b 100644
--- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
+++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
@@ -217,8 +217,10 @@ char *nullptr_zero(void) {
char *nullptr_one_BAD(void) {
// CHECK: define{{.*}} ptr @nullptr_one_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 false, label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 icmp eq (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64), i64 0), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64))
@@ -235,8 +237,10 @@ char *nullptr_one_BAD(void) {
char *nullptr_allones_BAD(void) {
// CHECK: define{{.*}} ptr @nullptr_allones_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 false, label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 icmp eq (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64), i64 0), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64))
@@ -264,9 +268,10 @@ char *one_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 1, %[[COMPUTED_OFFSET]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[OTHER_IS_NOT_NULL:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_NOT_NULL:.*]] = icmp ne i64 %[[COMPUTED_GEP]], 0, !nosanitize
- // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[OR_OV]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], 1, !nosanitize
// CHECK-SANITIZE-NEXT: %[[GEP_DID_NOT_OVERFLOW:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW]], !nosanitize
@@ -287,7 +292,9 @@ char *one_var(unsigned long offset) {
char *one_zero(void) {
// CHECK: define{{.*}} ptr @one_zero()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[CMP:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null
+ // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 %[[CMP]], true
+ // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1000]], i64 1, i64 1)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1000]], i64 1, i64 1)
@@ -304,9 +311,11 @@ char *one_zero(void) {
char *one_one_OK(void) {
// CHECK: define{{.*}} ptr @one_one_OK()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1))
@@ -323,9 +332,11 @@ char *one_one_OK(void) {
char *one_allones_BAD(void) {
// CHECK: define{{.*}} ptr @one_allones_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1))
@@ -353,9 +364,10 @@ char *allones_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 -1, %[[COMPUTED_OFFSET]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[OTHER_IS_NOT_NULL:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_NOT_NULL:.*]] = icmp ne i64 %[[COMPUTED_GEP]], 0, !nosanitize
- // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[OR_OV]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], -1, !nosanitize
// CHECK-SANITIZE-NEXT: %[[GEP_DID_NOT_OVERFLOW:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW]], !nosanitize
@@ -376,7 +388,9 @@ char *allones_var(unsigned long offset) {
char *allones_zero_OK(void) {
// CHECK: define{{.*}} ptr @allones_zero_OK()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[CMP:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 %[[CMP]], true, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1400]], i64 -1, i64 -1)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1400]], i64 -1, i64 -1)
@@ -393,9 +407,11 @@ char *allones_zero_OK(void) {
char *allones_one_BAD(void) {
// CHECK: define{{.*}} ptr @allones_one_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 -1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1))
@@ -412,9 +428,11 @@ char *allones_one_BAD(void) {
char *allones_allones_OK(void) {
// CHECK: define{{.*}} ptr @allones_allones_OK()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 -1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
...
[truncated]
|
@llvm/pr-subscribers-llvm-ir Author: Nikita Popov (nikic) ChangesDo not create icmp/fcmp constant expressions in IRBuilder etc anymore, i.e. treat them as "undesirable". This is in preparation for removing them entirely. Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179 Patch is 92.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92885.diff 40 Files Affected:
diff --git a/clang/test/Analysis/builtin_signbit.cpp b/clang/test/Analysis/builtin_signbit.cpp
index 57e6816ce2802..be10f0950f69b 100644
--- a/clang/test/Analysis/builtin_signbit.cpp
+++ b/clang/test/Analysis/builtin_signbit.cpp
@@ -84,28 +84,30 @@ long double ld = -1.0L;
// CHECK-LE-LABEL: define dso_local void @_Z12test_signbitv(
// CHECK-LE-SAME: ) #[[ATTR0:[0-9]+]] {
// CHECK-LE-NEXT: entry:
-// CHECK-LE-NEXT: [[FROMBOOL:%.*]] = zext i1 icmp slt (i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), i64 0) to i8
+// CHECK-LE-NEXT: [[TMP0:%.*]] = icmp slt i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), 0
+// CHECK-LE-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP0]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL]], ptr @b, align 1
-// CHECK-LE-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr @ld, align 16
-// CHECK-LE-NEXT: [[TMP1:%.*]] = bitcast ppc_fp128 [[TMP0]] to i128
-// CHECK-LE-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP1]] to i64
-// CHECK-LE-NEXT: [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 0
-// CHECK-LE-NEXT: [[FROMBOOL1:%.*]] = zext i1 [[TMP3]] to i8
+// CHECK-LE-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr @ld, align 16
+// CHECK-LE-NEXT: [[TMP2:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128
+// CHECK-LE-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i64
+// CHECK-LE-NEXT: [[TMP4:%.*]] = icmp slt i64 [[TMP3]], 0
+// CHECK-LE-NEXT: [[FROMBOOL1:%.*]] = zext i1 [[TMP4]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL1]], ptr @b, align 1
// CHECK-LE-NEXT: store i8 0, ptr @b, align 1
-// CHECK-LE-NEXT: [[TMP4:%.*]] = load double, ptr @d, align 8
-// CHECK-LE-NEXT: [[CONV:%.*]] = fptrunc double [[TMP4]] to float
-// CHECK-LE-NEXT: [[TMP5:%.*]] = bitcast float [[CONV]] to i32
-// CHECK-LE-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP5]], 0
-// CHECK-LE-NEXT: [[FROMBOOL2:%.*]] = zext i1 [[TMP6]] to i8
+// CHECK-LE-NEXT: [[TMP5:%.*]] = load double, ptr @d, align 8
+// CHECK-LE-NEXT: [[CONV:%.*]] = fptrunc double [[TMP5]] to float
+// CHECK-LE-NEXT: [[TMP6:%.*]] = bitcast float [[CONV]] to i32
+// CHECK-LE-NEXT: [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 0
+// CHECK-LE-NEXT: [[FROMBOOL2:%.*]] = zext i1 [[TMP7]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL2]], ptr @b, align 1
-// CHECK-LE-NEXT: [[FROMBOOL3:%.*]] = zext i1 icmp slt (i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), i64 0) to i8
+// CHECK-LE-NEXT: [[TMP8:%.*]] = icmp slt i64 trunc (i128 bitcast (ppc_fp128 0xM3FF00000000000000000000000000000 to i128) to i64), 0
+// CHECK-LE-NEXT: [[FROMBOOL3:%.*]] = zext i1 [[TMP8]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL3]], ptr @b, align 1
-// CHECK-LE-NEXT: [[TMP7:%.*]] = load ppc_fp128, ptr @ld, align 16
-// CHECK-LE-NEXT: [[TMP8:%.*]] = bitcast ppc_fp128 [[TMP7]] to i128
-// CHECK-LE-NEXT: [[TMP9:%.*]] = trunc i128 [[TMP8]] to i64
-// CHECK-LE-NEXT: [[TMP10:%.*]] = icmp slt i64 [[TMP9]], 0
-// CHECK-LE-NEXT: [[FROMBOOL4:%.*]] = zext i1 [[TMP10]] to i8
+// CHECK-LE-NEXT: [[TMP9:%.*]] = load ppc_fp128, ptr @ld, align 16
+// CHECK-LE-NEXT: [[TMP10:%.*]] = bitcast ppc_fp128 [[TMP9]] to i128
+// CHECK-LE-NEXT: [[TMP11:%.*]] = trunc i128 [[TMP10]] to i64
+// CHECK-LE-NEXT: [[TMP12:%.*]] = icmp slt i64 [[TMP11]], 0
+// CHECK-LE-NEXT: [[FROMBOOL4:%.*]] = zext i1 [[TMP12]] to i8
// CHECK-LE-NEXT: store i8 [[FROMBOOL4]], ptr @b, align 1
// CHECK-LE-NEXT: ret void
//
diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
index 015102940890a..e93dbcb9f647b 100644
--- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
+++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
@@ -217,8 +217,10 @@ char *nullptr_zero(void) {
char *nullptr_one_BAD(void) {
// CHECK: define{{.*}} ptr @nullptr_one_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 false, label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 icmp eq (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64), i64 0), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64))
@@ -235,8 +237,10 @@ char *nullptr_one_BAD(void) {
char *nullptr_allones_BAD(void) {
// CHECK: define{{.*}} ptr @nullptr_allones_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 false, label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 icmp eq (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64), i64 0), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP:.*]] = icmp ne i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 false, %[[CMP]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64))
@@ -264,9 +268,10 @@ char *one_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 1, %[[COMPUTED_OFFSET]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[OTHER_IS_NOT_NULL:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_NOT_NULL:.*]] = icmp ne i64 %[[COMPUTED_GEP]], 0, !nosanitize
- // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[OR_OV]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], 1, !nosanitize
// CHECK-SANITIZE-NEXT: %[[GEP_DID_NOT_OVERFLOW:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW]], !nosanitize
@@ -287,7 +292,9 @@ char *one_var(unsigned long offset) {
char *one_zero(void) {
// CHECK: define{{.*}} ptr @one_zero()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[CMP:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null
+ // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 %[[CMP]], true
+ // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1000]], i64 1, i64 1)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1000]], i64 1, i64 1)
@@ -304,9 +311,11 @@ char *one_zero(void) {
char *one_one_OK(void) {
// CHECK: define{{.*}} ptr @one_one_OK()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1))
@@ -323,9 +332,11 @@ char *one_one_OK(void) {
char *one_allones_BAD(void) {
// CHECK: define{{.*}} ptr @one_allones_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1))
@@ -353,9 +364,10 @@ char *allones_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[OR_OV:.+]] = or i1 %[[COMPUTED_OFFSET_OVERFLOWED]], false, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 -1, %[[COMPUTED_OFFSET]], !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[OTHER_IS_NOT_NULL:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_NOT_NULL:.*]] = icmp ne i64 %[[COMPUTED_GEP]], 0, !nosanitize
- // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[OTHER_IS_NOT_NULL]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[OR_OV]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], -1, !nosanitize
// CHECK-SANITIZE-NEXT: %[[GEP_DID_NOT_OVERFLOW:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW]], !nosanitize
@@ -376,7 +388,9 @@ char *allones_var(unsigned long offset) {
char *allones_zero_OK(void) {
// CHECK: define{{.*}} ptr @allones_zero_OK()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: br i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[CMP:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 %[[CMP]], true, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1400]], i64 -1, i64 -1)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1400]], i64 -1, i64 -1)
@@ -393,9 +407,11 @@ char *allones_zero_OK(void) {
char *allones_one_BAD(void) {
// CHECK: define{{.*}} ptr @allones_one_BAD()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 -1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1))
@@ -412,9 +428,11 @@ char *allones_one_BAD(void) {
char *allones_allones_OK(void) {
// CHECK: define{{.*}} ptr @allones_allones_OK()
// CHECK-NEXT: [[ENTRY:.*]]:
- // CHECK-SANITIZE-C-NEXT: %[[AND:.*]] = and i1 icmp ne (ptr inttoptr (i64 -1 to ptr), ptr null), icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), i64 0), !nosanitize
- // CHECK-SANITIZE-C-NEXT: br i1 %[[AND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
- // CHECK-SANITIZE-CPP-NEXT: br i1 xor (i1 icmp eq (ptr inttoptr (i64 -1 to ptr), ptr null), i1 icmp ne (i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), i64 0)), label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP1:.*]] = icmp ne ptr inttoptr (i64 -1 to ptr), null, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[CMP2:.*]] = icmp ne i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1), 0, !nosanitize
+ // CHECK-SANITIZE-C-NEXT: %[[COND:.*]] = and i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-CPP-NEXT: %[[COND:.*]] = icmp eq i1 %[[CMP1]], %[[CMP2]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[COND]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
...
[truncated]
|
@@ -43,9 +43,9 @@ | |||
; CHECK: @mul = global ptr null | |||
; CHECK: @xor = global ptr @A | |||
; CHECK: @B = external global %Ty | |||
; CHECK: @icmp_ult1 = global i1 icmp ugt (ptr getelementptr inbounds (i64, ptr @A, i64 1), ptr @A) | |||
; CHECK: @icmp_ult1 = global i1 icmp ult (ptr @A, ptr getelementptr inbounds (i64, ptr @A, i64 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few cases like this where we don't canonicalize constant expressions involving icmp anymore. This is because we also refuse to create new icmp expressions even if we already had one originally.
This is fine because it only happens if there was an icmp const expr in the first place, which will be removed shortly after this lands.
@@ -1422,7 +1417,7 @@ define i1 @user_of_not_called() { | |||
; CHECK-LABEL: define {{[^@]+}}@user_of_not_called() { | |||
; CHECK-NEXT: call void @useFnDecl(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called1 to ptr addrspace(42))) | |||
; CHECK-NEXT: call void @useFnDef(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called2 to ptr addrspace(42))) | |||
; CHECK-NEXT: ret i1 icmp eq (ptr addrspace(42) addrspacecast (ptr @not_called3 to ptr addrspace(42)), ptr addrspace(42) null) | |||
; CHECK-NEXT: ret i1 false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looked suspicious to me -- I was afraid that we started to simplify a null comparison through an addrspace cast, which wouldn't generally be valid. But this doesn't seem to be the case as far as ConstantFolding/InstSimplify are concerned. This is some Attributor-specific behavior and it has been flipping back and forth in this test in multiple previous changes. Maybe @jdoerfert knows what is happening here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -8,7 +8,8 @@ | |||
// CHECK: entry: | |||
// CHECK-NEXT: %retval = alloca i32 | |||
// CHECK-NEXT: store i32 0, ptr %retval | |||
// CHECK-NEXT: [[ZEXT:%.*]] = zext i1 true to i32 | |||
// CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @b, @a | |||
// CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks to be a missing constant fold somewhere. The compare should be folded to true, not a constantexpr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ignore me. I didn't realize this was specific testing unsimplified IR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember looking into this test a while ago (the zext i1 true
is pretty weird, usually IRBuilder would fold that away) and the context is that one of the values here gets RAUWed and that would enable the folding. For constant expressions, replacing an operand will also re-fold the expression. For instructions, this doesn't happen. In any case, it will get folded later if optimizations are enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
// CHECK-LE-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP1]] to i64 | ||
// CHECK-LE-NEXT: [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 0 | ||
// CHECK-LE-NEXT: [[FROMBOOL1:%.*]] = zext i1 [[TMP3]] to i8 | ||
// CHECK-LE-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr @ld, align 16 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That diff is awful. We should make update_cc_test_checks.py
use collect_original_check_lines
:)
Hello, some bots are broken after this patch:
FAIL: Clang::weak-external.cpp Could you look at this ? |
This broke the Mac LLDB builders for Fuchsia as well. I'm going to revert to unblock CI. |
This reverts commit 108575f.
Reverts #92885 due to LLDB CI breakages.
Unfortunately this is a Darwin-only test, and I don't have access to any MacOS systems. @JDevlieghere Could you please help me debug this issue? The test fails when trying to evaluate this expression: llvm-project/lldb/test/API/commands/expression/weak_symbols/TestWeakSymbols.py Lines 37 to 42 in 58ddf3a
|
If a weak function is missing, still return it's address (zero) rather than failing interpretation. Otherwise we have a mismatch between Interpret() and CanInterpret() resulting in failures that would not occur with JIT execution. Alternatively, we could try to look for weak symbols in CanInterpret() and generally reject them there. This is the root cause for the issue exposed by llvm#92885. Previously, the case affected by that always fell back to JIT because an icmp constant expression was used, which is not supported by the interpreter. Now a normal icmp instruction is used, which is supported. However, we fail to interpret due to incorrect handling of weak function addresses.
Okay, I managed to get access to a MacOS machine (turns out the GCC compile farm has one!) and figured out what the problem is. Basically, the presence of the constant expression meant that we previously always fell back to JIT and now we use the IR interpreter instead, which fails to handle the weak function symbol correctly. I put up a candidate fix at #93548. |
If a weak function is missing, still return it's address (zero) rather than failing interpretation. Otherwise we have a mismatch between Interpret() and CanInterpret() resulting in failures that would not occur with JIT execution. Alternatively, we could try to look for weak symbols in CanInterpret() and generally reject them there. This is the root cause for the issue exposed by #92885. Previously, the case affected by that always fell back to JIT because an icmp constant expression was used, which is not supported by the interpreter. Now a normal icmp instruction is used, which is supported. However, we fail to interpret due to incorrect handling of weak function addresses.
Reapply after #93548, which should address the lldb failure on macos. ----- Do not create icmp/fcmp constant expressions in IRBuilder etc anymore, i.e. treat them as "undesirable". This is in preparation for removing them entirely. Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
Hi @nikic The following starts crashing with this patch:
It hits
|
Similar to the change previously made for binops, make m_Trunc() only match instructions, not constant expressions. This is more likely to cause a crash than do something useful. Fixes crash reported at: #92885 (comment)
@mikaelholmen Thanks for the report, should be fixed by bda8d1a. |
Yep, thanks! That was fast! :) |
Do not create icmp/fcmp constant expressions in IRBuilder etc anymore, i.e. treat them as "undesirable". This is in preparation for removing them entirely.
Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179