From f8a36d8c3e264c4fccf8058e699201a452ea7bb7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 20 Jul 2023 14:31:18 +0200 Subject: [PATCH] [IR] Mark add constant expressions as undesirable In preparation for removing support for add expressions, mark them as undesirable. As such, we will no longer implicitly create such expressions, but they still exist. --- .../catch-nullptr-and-nonzero-offset.c | 12 +++++--- llvm/lib/IR/ConstantFold.cpp | 2 -- llvm/lib/IR/Constants.cpp | 2 +- .../CodeGen/Hexagon/atomic-opaque-basic.ll | 28 ++++++++----------- .../test/Transforms/InstCombine/bswap-fold.ll | 6 ++-- .../InstSimplify/ConstProp/constant-expr.ll | 2 +- llvm/test/Transforms/InstSimplify/compare.ll | 3 +- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c index 551ccc4810bcd3..0e0a9b157464a6 100644 --- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c +++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c @@ -303,7 +303,8 @@ char *one_zero(void) { char *one_one_OK(void) { // CHECK: define{{.*}} ptr @one_one_OK() // CHECK-NEXT: [[ENTRY:.*]]: - // CHECK-SANITIZE-C-NEXT: br i1 and (i1 icmp ne (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-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: [[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)) @@ -321,7 +322,8 @@ char *one_one_OK(void) { char *one_allones_BAD(void) { // CHECK: define{{.*}} ptr @one_allones_BAD() // CHECK-NEXT: [[ENTRY:.*]]: - // CHECK-SANITIZE-C-NEXT: br i1 and (i1 icmp ne (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-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: [[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)) @@ -390,7 +392,8 @@ char *allones_zero_OK(void) { char *allones_one_BAD(void) { // CHECK: define{{.*}} ptr @allones_one_BAD() // CHECK-NEXT: [[ENTRY:.*]]: - // CHECK-SANITIZE-C-NEXT: br i1 and (i1 icmp ne (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-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: [[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)) @@ -408,7 +411,8 @@ char *allones_one_BAD(void) { char *allones_allones_OK(void) { // CHECK: define{{.*}} ptr @allones_allones_OK() // CHECK-NEXT: [[ENTRY:.*]]: - // CHECK-SANITIZE-C-NEXT: br i1 and (i1 icmp ne (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-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: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1600]], 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)) diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 4c3325063c09d0..40b21876281142 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1241,8 +1241,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, case Instruction::Add: case Instruction::Sub: return ConstantExpr::getXor(C1, C2); - case Instruction::Mul: - return ConstantExpr::getAnd(C1, C2); case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index c69c7c095f7856..07b02c28cf9f25 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -2288,6 +2288,7 @@ bool ConstantExpr::isDesirableBinOp(unsigned Opcode) { case Instruction::FMul: case Instruction::FDiv: case Instruction::FRem: + case Instruction::And: return false; case Instruction::Add: case Instruction::Sub: @@ -2295,7 +2296,6 @@ bool ConstantExpr::isDesirableBinOp(unsigned Opcode) { case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: - case Instruction::And: case Instruction::Or: case Instruction::Xor: return true; diff --git a/llvm/test/CodeGen/Hexagon/atomic-opaque-basic.ll b/llvm/test/CodeGen/Hexagon/atomic-opaque-basic.ll index 61a877ae0ae73f..858bb20da7e38e 100644 --- a/llvm/test/CodeGen/Hexagon/atomic-opaque-basic.ll +++ b/llvm/test/CodeGen/Hexagon/atomic-opaque-basic.ll @@ -63,34 +63,30 @@ define void @f1() #0 { ; CHECK: .cfi_startproc ; CHECK-NEXT: // %bb.0: // %entry ; CHECK-NEXT: { -; CHECK-NEXT: r2 = ##g0 -; CHECK-NEXT: r0 = #255 +; CHECK-NEXT: r3 = ##g0 +; CHECK-NEXT: r1:0 = combine(#1,##255) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r1 = and(r2,#3) +; CHECK-NEXT: r2 = and(r3,#3) +; CHECK-NEXT: r3 = and(r3,#-4) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r1 = asl(r1,#3) -; CHECK-NEXT: } -; CHECK-NEXT: { -; CHECK-NEXT: r4 = r1 +; CHECK-NEXT: r2 = asl(r2,#3) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r4 = insert(r2,#2,#3) -; CHECK-NEXT: r2 = and(r2,#-4) +; CHECK-NEXT: r4 = asl(r0,r2) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r3 = lsl(#1,r4) -; CHECK-NEXT: r4 = asl(r0,r4) +; CHECK-NEXT: r4 = sub(#-1,r4) ; CHECK-NEXT: } ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: .LBB1_1: // %cmpxchg.start ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: { -; CHECK-NEXT: r5 = memw_locked(r2) +; CHECK-NEXT: r5 = memw_locked(r3) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r6 = lsr(r5,r1) +; CHECK-NEXT: r6 = lsr(r5,r2) ; CHECK-NEXT: } ; CHECK-NEXT: { ; CHECK-NEXT: p0 = !bitsclr(r6,r0) @@ -99,13 +95,13 @@ define void @f1() #0 { ; CHECK-NEXT: .LBB1_2: // %cmpxchg.trystore ; CHECK-NEXT: // in Loop: Header=BB1_1 Depth=1 ; CHECK-NEXT: { -; CHECK-NEXT: r6 = r3 +; CHECK-NEXT: r5 = and(r5,r4) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r6 |= and(r5,~r4) +; CHECK-NEXT: r5 |= asl(r1,r2) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: memw_locked(r2,p0) = r6 +; CHECK-NEXT: memw_locked(r3,p0) = r5 ; CHECK-NEXT: } ; CHECK-NEXT: { ; CHECK-NEXT: if (!p0) jump:nt .LBB1_1 diff --git a/llvm/test/Transforms/InstCombine/bswap-fold.ll b/llvm/test/Transforms/InstCombine/bswap-fold.ll index 844ae1ee3ca303..a9061d3c95ce98 100644 --- a/llvm/test/Transforms/InstCombine/bswap-fold.ll +++ b/llvm/test/Transforms/InstCombine/bswap-fold.ll @@ -786,7 +786,8 @@ define i64 @bs_all_operand64_multiuse_both(i64 %a, i64 %b) #0 { define void @bs_and_constexpr(ptr %out, i64 %a) { ; CHECK-LABEL: @bs_and_constexpr( -; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.bswap.i64(i64 and (i64 ptrtoint (ptr @gp to i64), i64 4095)) +; CHECK-NEXT: [[EXP:%.*]] = and i64 ptrtoint (ptr @gp to i64), 4095 +; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.bswap.i64(i64 [[EXP]]) ; CHECK-NEXT: store i64 [[RES]], ptr [[OUT:%.*]], align 8 ; CHECK-NEXT: ret void ; @@ -800,7 +801,8 @@ define void @bs_and_constexpr(ptr %out, i64 %a) { define void @bs_and_bs_constexpr(ptr %out, i64 %a) { ; CHECK-LABEL: @bs_and_bs_constexpr( -; CHECK-NEXT: store i64 and (i64 ptrtoint (ptr @gp to i64), i64 -67835469387268096), ptr [[OUT:%.*]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 ptrtoint (ptr @gp to i64), -67835469387268096 +; CHECK-NEXT: store i64 [[TMP1]], ptr [[OUT:%.*]], align 8 ; CHECK-NEXT: ret void ; %gpi = ptrtoint ptr @gp to i64 diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/constant-expr.ll b/llvm/test/Transforms/InstSimplify/ConstProp/constant-expr.ll index bdecda847d3727..55ee7b3a6cadc2 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/constant-expr.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/constant-expr.ll @@ -9,7 +9,7 @@ @B = global i1 sub (i1 icmp ult (ptr @X, ptr @Y), i1 icmp ult (ptr @X, ptr @Z)), align 2 ; CHECK: @B = global i1 xor (i1 icmp ult (ptr @X, ptr @Y), i1 icmp ult (ptr @X, ptr @Z)) @C = global i1 mul (i1 icmp ult (ptr @X, ptr @Y), i1 icmp ult (ptr @X, ptr @Z)) -; CHECK: @C = global i1 and (i1 icmp ult (ptr @X, ptr @Y), i1 icmp ult (ptr @X, ptr @Z)) +; CHECK: @C = global i1 mul (i1 icmp ult (ptr @X, ptr @Y), i1 icmp ult (ptr @X, ptr @Z)) @H = global i1 icmp ule (ptr @X, ptr @Y) ; CHECK: @H = global i1 icmp ule (ptr @X, ptr @Y) diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll index c62399c119c901..c6c104a41c8be7 100644 --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -490,7 +490,8 @@ define i1 @or(i32 %x) { define i1 @or_constexp(i32 %x) { ; CHECK-LABEL: @or_constexp( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[O:%.*]] = or i32 [[X:%.*]], and (i32 ptrtoint (ptr @GV to i32), i32 32) +; CHECK-NEXT: [[TMP0:%.*]] = and i32 ptrtoint (ptr @GV to i32), 32 +; CHECK-NEXT: [[O:%.*]] = or i32 [[X:%.*]], [[TMP0]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[O]], 0 ; CHECK-NEXT: ret i1 [[C]] ;