From 7037d110fab7e70c3951a4997779b3dd572ceb39 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 16 Jan 2022 13:36:49 -0500 Subject: [PATCH] [InstCombine] propagate IR flags from binop through select The tests with constant folding that produces poison could potentially remove the select entirely: https://alive2.llvm.org/ce/z/e-WUqF ...but this patch just removes the FMF-only limitation on propagation. --- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 12 +++++------- llvm/test/Transforms/InstCombine/select-2.ll | 12 ++++++------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index d689a48..d8544bf 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1027,13 +1027,11 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO, if (!ConstIsRHS) std::swap(Op0, Op1); - auto *BO = cast(&I); - Value *RI = Builder.CreateBinOp(BO->getOpcode(), Op0, Op1, - SO->getName() + ".op"); - auto *FPInst = dyn_cast(RI); - if (FPInst && isa(FPInst)) - FPInst->copyFastMathFlags(BO); - return RI; + Value *NewBO = Builder.CreateBinOp(cast(&I)->getOpcode(), Op0, + Op1, SO->getName() + ".op"); + if (auto *NewBOI = dyn_cast(NewBO)) + NewBOI->copyIRFlags(&I); + return NewBO; } Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, diff --git a/llvm/test/Transforms/InstCombine/select-2.ll b/llvm/test/Transforms/InstCombine/select-2.ll index 43e4ca8..a46c470 100644 --- a/llvm/test/Transforms/InstCombine/select-2.ll +++ b/llvm/test/Transforms/InstCombine/select-2.ll @@ -45,7 +45,7 @@ define float @t3(float %x, float %y) { define i8 @ashr_exact_poison_constant_fold(i1 %b, i8 %x) { ; CHECK-LABEL: @ashr_exact_poison_constant_fold( -; CHECK-NEXT: [[X_OP:%.*]] = ashr i8 [[X:%.*]], 3 +; CHECK-NEXT: [[X_OP:%.*]] = ashr exact i8 [[X:%.*]], 3 ; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 [[X_OP]], i8 5 ; CHECK-NEXT: ret i8 [[R]] ; @@ -56,7 +56,7 @@ define i8 @ashr_exact_poison_constant_fold(i1 %b, i8 %x) { define i8 @ashr_exact(i1 %b, i8 %x) { ; CHECK-LABEL: @ashr_exact( -; CHECK-NEXT: [[X_OP:%.*]] = ashr i8 [[X:%.*]], 3 +; CHECK-NEXT: [[X_OP:%.*]] = ashr exact i8 [[X:%.*]], 3 ; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 [[X_OP]], i8 2 ; CHECK-NEXT: ret i8 [[R]] ; @@ -67,7 +67,7 @@ define i8 @ashr_exact(i1 %b, i8 %x) { define i8 @shl_nsw_nuw_poison_constant_fold(i1 %b, i8 %x) { ; CHECK-LABEL: @shl_nsw_nuw_poison_constant_fold( -; CHECK-NEXT: [[X_OP:%.*]] = shl i8 16, [[X:%.*]] +; CHECK-NEXT: [[X_OP:%.*]] = shl nuw nsw i8 16, [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 -128, i8 [[X_OP]] ; CHECK-NEXT: ret i8 [[R]] ; @@ -78,7 +78,7 @@ define i8 @shl_nsw_nuw_poison_constant_fold(i1 %b, i8 %x) { define i8 @shl_nsw_nuw(i1 %b, i8 %x) { ; CHECK-LABEL: @shl_nsw_nuw( -; CHECK-NEXT: [[X_OP:%.*]] = shl i8 7, [[X:%.*]] +; CHECK-NEXT: [[X_OP:%.*]] = shl nuw nsw i8 7, [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 56, i8 [[X_OP]] ; CHECK-NEXT: ret i8 [[R]] ; @@ -89,7 +89,7 @@ define i8 @shl_nsw_nuw(i1 %b, i8 %x) { define i8 @add_nsw_poison_constant_fold(i1 %b, i8 %x) { ; CHECK-LABEL: @add_nsw_poison_constant_fold( -; CHECK-NEXT: [[X_OP:%.*]] = add i8 [[X:%.*]], 64 +; CHECK-NEXT: [[X_OP:%.*]] = add nsw i8 [[X:%.*]], 64 ; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 [[X_OP]], i8 -127 ; CHECK-NEXT: ret i8 [[R]] ; @@ -100,7 +100,7 @@ define i8 @add_nsw_poison_constant_fold(i1 %b, i8 %x) { define i8 @add_nsw(i1 %b, i8 %x) { ; CHECK-LABEL: @add_nsw( -; CHECK-NEXT: [[X_OP:%.*]] = add i8 [[X:%.*]], 64 +; CHECK-NEXT: [[X_OP:%.*]] = add nsw i8 [[X:%.*]], 64 ; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 [[X_OP]], i8 71 ; CHECK-NEXT: ret i8 [[R]] ; -- 2.7.4