Skip to content

Commit 9c8eb1e

Browse files
committed
[InstCombine] Copy flags of extractelement for extelt -> icmp combine
1 parent 20e0bac commit 9c8eb1e

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,17 @@ class CmpInst : public Instruction {
10581058
static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1,
10591059
Value *S2, const Twine &Name, BasicBlock *InsertAtEnd);
10601060

1061+
/// Construct a compare instruction, given the opcode, the predicate,
1062+
/// the two operands and the instruction to copy the flags from. Optionally
1063+
/// (if InstBefore is specified) insert the instruction into a BasicBlock
1064+
/// right before the specified instruction. The specified Instruction is
1065+
/// allowed to be a dereferenced end iterator. Create a CmpInst
1066+
static CmpInst *CreateWithCopiedFlags(OtherOps Op, Predicate Pred, Value *S1,
1067+
Value *S2,
1068+
const Instruction *FlagsSource,
1069+
const Twine &Name = "",
1070+
Instruction *InsertBefore = nullptr);
1071+
10611072
/// Get the opcode casted to the right type
10621073
OtherOps getOpcode() const {
10631074
return static_cast<OtherOps>(Instruction::getOpcode());

llvm/lib/IR/Instructions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4623,6 +4623,16 @@ CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2,
46234623
S1, S2, Name);
46244624
}
46254625

4626+
CmpInst *CmpInst::CreateWithCopiedFlags(OtherOps Op, Predicate Pred, Value *S1,
4627+
Value *S2,
4628+
const Instruction *FlagsSource,
4629+
const Twine &Name,
4630+
Instruction *InsertBefore) {
4631+
CmpInst *Inst = Create(Op, Pred, S1, S2, Name, InsertBefore);
4632+
Inst->copyIRFlags(FlagsSource);
4633+
return Inst;
4634+
}
4635+
46264636
void CmpInst::swapOperands() {
46274637
if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
46284638
IC->swapOperands();

llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
487487
// extelt (cmp X, Y), Index --> cmp (extelt X, Index), (extelt Y, Index)
488488
Value *E0 = Builder.CreateExtractElement(X, Index);
489489
Value *E1 = Builder.CreateExtractElement(Y, Index);
490-
return CmpInst::Create(cast<CmpInst>(SrcVec)->getOpcode(), Pred, E0, E1);
490+
Instruction *SrcInst = cast<Instruction>(SrcVec);
491+
return CmpInst::CreateWithCopiedFlags(cast<CmpInst>(SrcVec)->getOpcode(),
492+
Pred, E0, E1, SrcInst);
491493
}
492494

493495
if (auto *I = dyn_cast<Instruction>(SrcVec)) {

llvm/test/Transforms/InstCombine/scalarization.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,20 @@ define i1 @extractelt_vector_fcmp_constrhs_dynidx(<2 x float> %arg, i32 %idx) {
341341
ret i1 %ext
342342
}
343343

344+
define i1 @extractelt_vector_fcmp_copy_flags(<4 x float> %x, <4 x i1> %y) {
345+
; CHECK-LABEL: @extractelt_vector_fcmp_copy_flags(
346+
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i64 2
347+
; CHECK-NEXT: [[TMP2:%.*]] = fcmp nsz arcp oeq float [[TMP1]], 0.000000e+00
348+
; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[Y:%.*]], i64 2
349+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP3]]
350+
; CHECK-NEXT: ret i1 [[R]]
351+
;
352+
%cmp = fcmp nsz arcp oeq <4 x float> %x, zeroinitializer
353+
%and = and <4 x i1> %cmp, %y
354+
%r = extractelement <4 x i1> %and, i32 2
355+
ret i1 %r
356+
}
357+
344358
define i1 @extractelt_vector_fcmp_not_cheap_to_scalarize_multi_use(<2 x float> %arg0, <2 x float> %arg1, <2 x float> %arg2, i32 %idx) {
345359
;
346360
; CHECK-LABEL: @extractelt_vector_fcmp_not_cheap_to_scalarize_multi_use(

0 commit comments

Comments
 (0)