Skip to content
7 changes: 7 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1719,6 +1719,13 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
if (SI->getType()->isIntOrIntVectorTy(1))
return nullptr;

if (isa<MinMaxIntrinsic>(&Op))
for (Value *IntrinOp : Op.operands())
if (auto *PN = dyn_cast<PHINode>(IntrinOp))
for (Value *PhiOp : PN->operands())
if (PhiOp == &Op)
return nullptr;

// Test if a FCmpInst instruction is used exclusively by a select as
// part of a minimum or maximum operation. If so, refrain from doing
// any other folding. This helps out other analyses which understand
Expand Down
15 changes: 15 additions & 0 deletions llvm/test/Transforms/InstCombine/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5047,3 +5047,18 @@ define <2 x ptr> @select_freeze_constant_expression_vector_gep(i1 %cond, <2 x pt
%sel = select i1 %cond, <2 x ptr> %y, <2 x ptr> %freeze
ret <2 x ptr> %sel
}

; declare i8 @llvm.umin.i8(i8, i8)
;
; define i8 @no_fold_masked_min(i8 %acc, i8 %val, i8 %mask) {
; ; CHECK-LABEL: @no_fold_masked_min(
; ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[MASK:%.*]], 0
; ; CHECK-NEXT: [[MASKED_VAL:%.*]] = select i1 [[COND:%.*]], i8 [[VAL:%.*]], i8 -1
; ; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.umin.i8(i8 [[ACC:%.*]], i8 [[MASKED_VAL:%.*]])
; ; CHECK-NEXT: ret i8 [[RES]]
; ;
; %cond = icmp eq i8 %mask, 0
; %masked_val = select i1 %cond, i8 %val, i8 -1
; %res = call i8 @llvm.umin.i8(i8 %acc, i8 %masked_val)
; ret i8 %res
; }
Loading