diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 369ac4220beadb..e5b0345e7970a2 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5020,7 +5020,8 @@ static bool directlyImpliesPoison(const Value *ValAssumedPoison, // V0's elements are all poison or not. (e.g., add_with_overflow) const WithOverflowInst *II; if (match(I, m_ExtractValue(m_WithOverflowInst(II))) && - match(ValAssumedPoison, m_ExtractValue(m_Specific(II)))) + (match(ValAssumedPoison, m_ExtractValue(m_Specific(II))) || + llvm::is_contained(II->arg_operands(), ValAssumedPoison))) return true; } return false; diff --git a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov-not.ll b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov-not.ll index 170b072dbdb65f..57cef74aec7f90 100644 --- a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov-not.ll +++ b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov-not.ll @@ -21,12 +21,10 @@ define i1 @t0_umul(i4 %size, i4 %nmemb) { define i1 @t1_commutative(i4 %size, i4 %nmemb) { ; CHECK-LABEL: @t1_commutative( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i4 [[SIZE:%.*]], 0 -; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) +; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE:%.*]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1 ; CHECK-NEXT: [[PHITMP:%.*]] = xor i1 [[SMUL_OV]], true -; CHECK-NEXT: [[OR:%.*]] = select i1 [[PHITMP]], i1 true, i1 [[CMP]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: ret i1 [[PHITMP]] ; %cmp = icmp eq i4 %size, 0 %smul = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 %size, i4 %nmemb) diff --git a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov.ll b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov.ll index 7d4744ccc584e9..bf86f43b543281 100644 --- a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov.ll +++ b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov.ll @@ -5,11 +5,9 @@ declare { i4, i1 } @llvm.smul.with.overflow.i4(i4, i4) #1 define i1 @t0_smul(i4 %size, i4 %nmemb) { ; CHECK-LABEL: @t0_smul( -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 0 -; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) +; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE:%.*]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[SMUL_OV]], i1 [[CMP]], i1 false -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: ret i1 [[SMUL_OV]] ; %cmp = icmp ne i4 %size, 0 %smul = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 %size, i4 %nmemb) @@ -52,7 +50,7 @@ define i1 @n3_wrong_pred(i4 %size, i4 %nmemb) { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i4 [[SIZE:%.*]], 0 ; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[SMUL_OV]], i1 [[CMP]], i1 false +; CHECK-NEXT: [[AND:%.*]] = and i1 [[SMUL_OV]], [[CMP]] ; CHECK-NEXT: ret i1 [[AND]] ; %cmp = icmp eq i4 %size, 0 ; not 'ne' @@ -67,7 +65,7 @@ define i1 @n4_not_and(i4 %size, i4 %nmemb) { ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 0 ; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[SMUL_OV]], i1 true, i1 [[CMP]] +; CHECK-NEXT: [[AND:%.*]] = or i1 [[SMUL_OV]], [[CMP]] ; CHECK-NEXT: ret i1 [[AND]] ; %cmp = icmp ne i4 %size, 0 @@ -82,7 +80,7 @@ define i1 @n5_not_zero(i4 %size, i4 %nmemb) { ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 1 ; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[SMUL_OV]], i1 [[CMP]], i1 false +; CHECK-NEXT: [[AND:%.*]] = and i1 [[SMUL_OV]], [[CMP]] ; CHECK-NEXT: ret i1 [[AND]] ; %cmp = icmp ne i4 %size, 1 ; should be '0' diff --git a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov-not.ll b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov-not.ll index 8468aa79830c05..b039cc832f12b0 100644 --- a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov-not.ll +++ b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov-not.ll @@ -21,12 +21,10 @@ define i1 @t0_umul(i4 %size, i4 %nmemb) { define i1 @t1_commutative(i4 %size, i4 %nmemb) { ; CHECK-LABEL: @t1_commutative( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i4 [[SIZE:%.*]], 0 -; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) +; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE:%.*]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1 ; CHECK-NEXT: [[PHITMP:%.*]] = xor i1 [[UMUL_OV]], true -; CHECK-NEXT: [[OR:%.*]] = select i1 [[PHITMP]], i1 true, i1 [[CMP]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: ret i1 [[PHITMP]] ; %cmp = icmp eq i4 %size, 0 %umul = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 %size, i4 %nmemb) diff --git a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov.ll b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov.ll index 19d33f35106edc..598ce5f2fa8d60 100644 --- a/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov.ll +++ b/llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov.ll @@ -5,11 +5,9 @@ declare { i4, i1 } @llvm.umul.with.overflow.i4(i4, i4) #1 define i1 @t0_umul(i4 %size, i4 %nmemb) { ; CHECK-LABEL: @t0_umul( -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 0 -; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) +; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE:%.*]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[UMUL_OV]], i1 [[CMP]], i1 false -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: ret i1 [[UMUL_OV]] ; %cmp = icmp ne i4 %size, 0 %umul = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 %size, i4 %nmemb) @@ -52,7 +50,7 @@ define i1 @n3_wrong_pred(i4 %size, i4 %nmemb) { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i4 [[SIZE:%.*]], 0 ; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[UMUL_OV]], i1 [[CMP]], i1 false +; CHECK-NEXT: [[AND:%.*]] = and i1 [[UMUL_OV]], [[CMP]] ; CHECK-NEXT: ret i1 [[AND]] ; %cmp = icmp eq i4 %size, 0 ; not 'ne' @@ -67,7 +65,7 @@ define i1 @n4_not_and(i4 %size, i4 %nmemb) { ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 0 ; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[UMUL_OV]], i1 true, i1 [[CMP]] +; CHECK-NEXT: [[AND:%.*]] = or i1 [[UMUL_OV]], [[CMP]] ; CHECK-NEXT: ret i1 [[AND]] ; %cmp = icmp ne i4 %size, 0 @@ -82,7 +80,7 @@ define i1 @n5_not_zero(i4 %size, i4 %nmemb) { ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 1 ; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]]) ; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1 -; CHECK-NEXT: [[AND:%.*]] = select i1 [[UMUL_OV]], i1 [[CMP]], i1 false +; CHECK-NEXT: [[AND:%.*]] = and i1 [[UMUL_OV]], [[CMP]] ; CHECK-NEXT: ret i1 [[AND]] ; %cmp = icmp ne i4 %size, 1 ; should be '0'