[llvm] ValueTracking: introduce llvm::isLanewiseOperation (PR #112011)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 11 12:40:30 PDT 2024
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/112011
>From b2a744682e24361cc417793e8877aa48b9d63fc9 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Fri, 11 Oct 2024 16:39:07 +0100
Subject: [PATCH 1/3] ValueTracking: introduce llvm::isLanewiseOperation
Factor out and unify common code from InstSimplify and InstCombine that
partially guard against cross-lane vector operations into
llvm::isLanewiseOperation in ValueTracking.
Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/r9jCpP
---
llvm/include/llvm/Analysis/ValueTracking.h | 4 ++++
llvm/lib/Analysis/InstructionSimplify.cpp | 8 +++----
llvm/lib/Analysis/ValueTracking.cpp | 24 +++++++++++++++++++
.../InstCombine/InstCombineCalls.cpp | 17 +------------
llvm/test/Transforms/InstCombine/ispow2.ll | 12 ++--------
.../InstCombine/select-ctlz-to-cttz.ll | 4 +---
llvm/test/Transforms/InstSimplify/select.ll | 7 ++----
7 files changed, 37 insertions(+), 39 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 5749a34d511dd7..780b88107fd67b 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -791,6 +791,10 @@ bool onlyUsedByLifetimeMarkers(const Value *V);
/// droppable instructions.
bool onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V);
+/// Return true if the instruction is known to be a vector lane-wise operation
+/// i.e. if it doesn't potentially cross vector lanes.
+bool isLanewiseOperation(const Instruction *I);
+
/// Return true if the instruction does not have any effects besides
/// calculating the result and does not have undefined behavior.
///
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 90f05d43a2b147..c84292fb30cd4d 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4343,13 +4343,11 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
if (isa<PHINode>(I))
return nullptr;
- if (Op->getType()->isVectorTy()) {
+ if (Op->getType()->isVectorTy() &&
+ (!I->getType()->isVectorTy() || !isLanewiseOperation(I)))
// For vector types, the simplification must hold per-lane, so forbid
// potentially cross-lane operations like shufflevector.
- if (!I->getType()->isVectorTy() || isa<ShuffleVectorInst>(I) ||
- isa<CallBase>(I) || isa<BitCastInst>(I))
- return nullptr;
- }
+ return nullptr;
// Don't fold away llvm.is.constant checks based on assumptions.
if (match(I, m_Intrinsic<Intrinsic::is_constant>()))
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 446ff42f3e243d..284123777a5350 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6947,6 +6947,30 @@ bool llvm::onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V) {
V, /* AllowLifetime */ true, /* AllowDroppable */ true);
}
+bool llvm::isLanewiseOperation(const Instruction *I) {
+ if (auto *II = dyn_cast<IntrinsicInst>(I)) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ case Intrinsic::ctpop:
+ case Intrinsic::umin:
+ case Intrinsic::umax:
+ case Intrinsic::smin:
+ case Intrinsic::smax:
+ case Intrinsic::usub_sat:
+ case Intrinsic::uadd_sat:
+ case Intrinsic::ssub_sat:
+ case Intrinsic::sadd_sat:
+ return true;
+ default:
+ return false;
+ }
+ }
+ auto *Shuffle = dyn_cast<ShuffleVectorInst>(I);
+ return (!Shuffle || Shuffle->isIdentity() || Shuffle->isSelect()) &&
+ !isa<CallBase>(I) && !isa<BitCastInst>(I);
+}
+
bool llvm::isSafeToSpeculativelyExecute(const Instruction *Inst,
const Instruction *CtxI,
AssumptionCache *AC,
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index f7a9406791801c..be9d3e3abd2df5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3629,26 +3629,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// * The intrinsic is speculatable.
// * The select condition is not a vector, or the intrinsic does not
// perform cross-lane operations.
- switch (IID) {
- case Intrinsic::ctlz:
- case Intrinsic::cttz:
- case Intrinsic::ctpop:
- case Intrinsic::umin:
- case Intrinsic::umax:
- case Intrinsic::smin:
- case Intrinsic::smax:
- case Intrinsic::usub_sat:
- case Intrinsic::uadd_sat:
- case Intrinsic::ssub_sat:
- case Intrinsic::sadd_sat:
+ if (isLanewiseOperation(II))
for (Value *Op : II->args())
if (auto *Sel = dyn_cast<SelectInst>(Op))
if (Instruction *R = FoldOpIntoSelect(*II, Sel))
return R;
- [[fallthrough]];
- default:
- break;
- }
if (Instruction *Shuf = foldShuffledIntrinsicOperands(II, Builder))
return Shuf;
diff --git a/llvm/test/Transforms/InstCombine/ispow2.ll b/llvm/test/Transforms/InstCombine/ispow2.ll
index c21ad95f83a1c4..2bc629a5cddf24 100644
--- a/llvm/test/Transforms/InstCombine/ispow2.ll
+++ b/llvm/test/Transforms/InstCombine/ispow2.ll
@@ -977,11 +977,7 @@ define i1 @is_pow2or0_ctpop_wrong_pred2_logical(i32 %x) {
define <2 x i1> @is_pow2or0_ctpop_commute_vec_wrong_pred3(<2 x i8> %x) {
; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec_wrong_pred3(
-; CHECK-NEXT: [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[T0]], <i8 1, i8 1>
-; CHECK-NEXT: [[ISZERO:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[CMP]], [[ISZERO]]
-; CHECK-NEXT: ret <2 x i1> [[R]]
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
%cmp = icmp eq <2 x i8> %t0, <i8 1, i8 1>
@@ -1174,11 +1170,7 @@ define i1 @isnot_pow2nor0_ctpop_wrong_pred2_logical(i32 %x) {
define <2 x i1> @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(<2 x i8> %x) {
; CHECK-LABEL: @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(
-; CHECK-NEXT: [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[T0]], <i8 1, i8 1>
-; CHECK-NEXT: [[NOTZERO:%.*]] = icmp ne <2 x i8> [[X]], zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[CMP]], [[NOTZERO]]
-; CHECK-NEXT: ret <2 x i1> [[R]]
+; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
%cmp = icmp ne <2 x i8> %t0, <i8 1, i8 1>
diff --git a/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll b/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
index cc8f5d53fddddd..2e6fe26c03051b 100644
--- a/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
+++ b/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
@@ -208,10 +208,8 @@ define <2 x i32> @select_clz_to_ctz_vec_with_undef(<2 x i32> %a) {
; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[A:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A]], [[SUB]]
; CHECK-NEXT: [[LZ:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[AND]], i1 true)
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq <2 x i32> [[A]], zeroinitializer
; CHECK-NEXT: [[SUB1:%.*]] = xor <2 x i32> [[LZ]], <i32 31, i32 undef>
-; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i32> [[LZ]], <2 x i32> [[SUB1]]
-; CHECK-NEXT: ret <2 x i32> [[COND]]
+; CHECK-NEXT: ret <2 x i32> [[SUB1]]
;
%sub = sub <2 x i32> zeroinitializer, %a
%and = and <2 x i32> %sub, %a
diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll
index 1e503afae1a69d..4618e1143dc8f9 100644
--- a/llvm/test/Transforms/InstSimplify/select.ll
+++ b/llvm/test/Transforms/InstSimplify/select.ll
@@ -1087,13 +1087,10 @@ define i32 @select_ctpop_zero(i32 %x) {
ret i32 %sel
}
-; FIXME: This is safe to fold.
define <2 x i32> @select_ctpop_zero_vec(<2 x i32> %x) {
; CHECK-LABEL: @select_ctpop_zero_vec(
-; CHECK-NEXT: [[T0:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
-; CHECK-NEXT: [[T1:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X]])
-; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[T0]], <2 x i32> zeroinitializer, <2 x i32> [[T1]]
-; CHECK-NEXT: ret <2 x i32> [[SEL]]
+; CHECK-NEXT: [[T1:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
+; CHECK-NEXT: ret <2 x i32> [[T1]]
;
%t0 = icmp eq <2 x i32> %x, zeroinitializer
%t1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %x)
>From ce575efc5679920ad97218515472d8256c1b5c86 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Fri, 11 Oct 2024 19:46:50 +0100
Subject: [PATCH 2/3] ValueTracking, InstSimplify: more test updates
Fix a few things for more correct test updates!
---
llvm/lib/Analysis/InstructionSimplify.cpp | 3 +--
llvm/lib/Analysis/ValueTracking.cpp | 21 +++++++++++++------
.../InstCombine/InstCombineCalls.cpp | 2 +-
.../InstCombine/simplify-demanded-fpclass.ll | 4 ++--
.../Transforms/InstSimplify/select-abs.ll | 19 ++++++-----------
5 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index c84292fb30cd4d..376563eb9e345d 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4343,8 +4343,7 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
if (isa<PHINode>(I))
return nullptr;
- if (Op->getType()->isVectorTy() &&
- (!I->getType()->isVectorTy() || !isLanewiseOperation(I)))
+ if (Op->getType()->isVectorTy() && !isLanewiseOperation(I))
// For vector types, the simplification must hold per-lane, so forbid
// potentially cross-lane operations like shufflevector.
return nullptr;
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 284123777a5350..620af47ceacce6 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6950,13 +6950,21 @@ bool llvm::onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V) {
bool llvm::isLanewiseOperation(const Instruction *I) {
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
switch (II->getIntrinsicID()) {
+ // TODO: expand this list.
+ case Intrinsic::abs:
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ case Intrinsic::umax:
+ case Intrinsic::umin:
+ case Intrinsic::powi:
+ case Intrinsic::bitreverse:
+ case Intrinsic::bswap:
+ case Intrinsic::ctpop:
case Intrinsic::ctlz:
case Intrinsic::cttz:
- case Intrinsic::ctpop:
- case Intrinsic::umin:
- case Intrinsic::umax:
- case Intrinsic::smin:
- case Intrinsic::smax:
+ case Intrinsic::fshl:
+ case Intrinsic::fshr:
+ case Intrinsic::copysign:
case Intrinsic::usub_sat:
case Intrinsic::uadd_sat:
case Intrinsic::ssub_sat:
@@ -6968,7 +6976,8 @@ bool llvm::isLanewiseOperation(const Instruction *I) {
}
auto *Shuffle = dyn_cast<ShuffleVectorInst>(I);
return (!Shuffle || Shuffle->isIdentity() || Shuffle->isSelect()) &&
- !isa<CallBase>(I) && !isa<BitCastInst>(I);
+ !isa<CallBase>(I) && !isa<BitCastInst>(I) &&
+ !isa<ExtractElementInst>(I);
}
bool llvm::isSafeToSpeculativelyExecute(const Instruction *Inst,
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index be9d3e3abd2df5..a72364e061fb49 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3629,7 +3629,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// * The intrinsic is speculatable.
// * The select condition is not a vector, or the intrinsic does not
// perform cross-lane operations.
- if (isLanewiseOperation(II))
+ if (isSafeToSpeculativelyExecute(&CI) && isLanewiseOperation(II))
for (Value *Op : II->args())
if (auto *Sel = dyn_cast<SelectInst>(Op))
if (Instruction *R = FoldOpIntoSelect(*II, Sel))
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index f1f1708333901a..65faf0974b503f 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -998,8 +998,8 @@ define nofpclass(nan inf) float @pow_f32(float nofpclass(nan inf) %arg, float no
; CHECK-NEXT: [[I12:%.*]] = select i1 [[I11]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT: [[I13:%.*]] = tail call noundef float @llvm.copysign.f32(float noundef [[I4]], float noundef [[I12]])
; CHECK-NEXT: [[I17:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00
-; CHECK-NEXT: [[I21:%.*]] = select i1 [[I11]], float [[ARG]], float 0.000000e+00
-; CHECK-NEXT: [[I22:%.*]] = tail call noundef nofpclass(nan sub norm) float @llvm.copysign.f32(float noundef 0.000000e+00, float noundef [[I21]])
+; CHECK-NEXT: [[TMP0:%.*]] = tail call nofpclass(nan sub norm) float @llvm.copysign.f32(float 0.000000e+00, float [[ARG]])
+; CHECK-NEXT: [[I22:%.*]] = select i1 [[I11]], float [[TMP0]], float 0.000000e+00
; CHECK-NEXT: [[I23:%.*]] = select i1 [[I17]], float [[I22]], float [[I13]]
; CHECK-NEXT: [[I24:%.*]] = fcmp oeq float [[ARG]], 1.000000e+00
; CHECK-NEXT: [[I25:%.*]] = fcmp oeq float [[ARG1]], 0.000000e+00
diff --git a/llvm/test/Transforms/InstSimplify/select-abs.ll b/llvm/test/Transforms/InstSimplify/select-abs.ll
index 6b4708443fb261..dad2dc620c7c7c 100644
--- a/llvm/test/Transforms/InstSimplify/select-abs.ll
+++ b/llvm/test/Transforms/InstSimplify/select-abs.ll
@@ -232,14 +232,11 @@ entry:
ret i64 %res
}
-; TODO: Handle vector cases?
define <4 x i16> @select_v4i16_eq0_abs_t(<4 x i16> %a) {
; CHECK-LABEL: @select_v4i16_eq0_abs_t(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[COND:%.*]] = icmp eq <4 x i16> [[A:%.*]], zeroinitializer
-; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
-; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> zeroinitializer, <4 x i16> [[ABS]]
-; CHECK-NEXT: ret <4 x i16> [[RES]]
+; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A:%.*]], i1 true)
+; CHECK-NEXT: ret <4 x i16> [[ABS]]
;
entry:
%cond = icmp eq <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
@@ -251,10 +248,8 @@ entry:
define <4 x i16> @select_v4i16_ne0_abs_t(<4 x i16> %a) {
; CHECK-LABEL: @select_v4i16_ne0_abs_t(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], zeroinitializer
-; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
-; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> zeroinitializer
-; CHECK-NEXT: ret <4 x i16> [[RES]]
+; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A:%.*]], i1 true)
+; CHECK-NEXT: ret <4 x i16> [[ABS]]
;
entry:
%cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
@@ -305,10 +300,8 @@ entry:
define <4 x i16> @badsplat1_select_v4i16_ne0_abs(<4 x i16> %a) {
; CHECK-LABEL: @badsplat1_select_v4i16_ne0_abs(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], <i16 0, i16 1, i16 0, i16 0>
-; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
-; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 0, i16 1, i16 0, i16 0>
-; CHECK-NEXT: ret <4 x i16> [[RES]]
+; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A:%.*]], i1 true)
+; CHECK-NEXT: ret <4 x i16> [[ABS]]
;
entry:
%cond = icmp ne <4 x i16> %a, <i16 0, i16 1, i16 0, i16 0>
>From daf4721ca1aa1fd5e1712859740dd8b60e8e8fe0 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Fri, 11 Oct 2024 20:38:29 +0100
Subject: [PATCH 3/3] ValueTracking: a more complete list, multi-arg isa
---
llvm/lib/Analysis/ValueTracking.cpp | 48 +++++++++++++++++++++++++++--
1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 620af47ceacce6..559c1f068b9530 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6956,7 +6956,45 @@ bool llvm::isLanewiseOperation(const Instruction *I) {
case Intrinsic::smin:
case Intrinsic::umax:
case Intrinsic::umin:
+ case Intrinsic::sqrt:
case Intrinsic::powi:
+ case Intrinsic::sin:
+ case Intrinsic::cos:
+ case Intrinsic::tan:
+ case Intrinsic::asin:
+ case Intrinsic::acos:
+ case Intrinsic::atan:
+ case Intrinsic::atan2:
+ case Intrinsic::sinh:
+ case Intrinsic::cosh:
+ case Intrinsic::tanh:
+ case Intrinsic::pow:
+ case Intrinsic::exp:
+ case Intrinsic::exp2:
+ case Intrinsic::exp10:
+ case Intrinsic::ldexp:
+ case Intrinsic::frexp:
+ case Intrinsic::log:
+ case Intrinsic::log10:
+ case Intrinsic::log2:
+ case Intrinsic::fma:
+ case Intrinsic::fabs:
+ case Intrinsic::minimum:
+ case Intrinsic::maximum:
+ case Intrinsic::minimumnum:
+ case Intrinsic::maximumnum:
+ case Intrinsic::copysign:
+ case Intrinsic::floor:
+ case Intrinsic::ceil:
+ case Intrinsic::trunc:
+ case Intrinsic::rint:
+ case Intrinsic::nearbyint:
+ case Intrinsic::round:
+ case Intrinsic::roundeven:
+ case Intrinsic::lround:
+ case Intrinsic::llround:
+ case Intrinsic::lrint:
+ case Intrinsic::llrint:
case Intrinsic::bitreverse:
case Intrinsic::bswap:
case Intrinsic::ctpop:
@@ -6964,11 +7002,16 @@ bool llvm::isLanewiseOperation(const Instruction *I) {
case Intrinsic::cttz:
case Intrinsic::fshl:
case Intrinsic::fshr:
- case Intrinsic::copysign:
case Intrinsic::usub_sat:
case Intrinsic::uadd_sat:
+ case Intrinsic::ushl_sat:
case Intrinsic::ssub_sat:
case Intrinsic::sadd_sat:
+ case Intrinsic::sshl_sat:
+ case Intrinsic::canonicalize:
+ case Intrinsic::fmuladd:
+ case Intrinsic::fptoui_sat:
+ case Intrinsic::fptosi_sat:
return true;
default:
return false;
@@ -6976,8 +7019,7 @@ bool llvm::isLanewiseOperation(const Instruction *I) {
}
auto *Shuffle = dyn_cast<ShuffleVectorInst>(I);
return (!Shuffle || Shuffle->isIdentity() || Shuffle->isSelect()) &&
- !isa<CallBase>(I) && !isa<BitCastInst>(I) &&
- !isa<ExtractElementInst>(I);
+ !isa<CallBase, BitCastInst, ExtractElementInst>(I);
}
bool llvm::isSafeToSpeculativelyExecute(const Instruction *Inst,
More information about the llvm-commits
mailing list