[llvm] 64e768e - [ValueTracking] Improve impliesPoison to look into overflow intrinsics

Juneyoung Lee via llvm-commits llvm-commits at lists.llvm.org
Sat May 1 20:04:04 PDT 2021


Author: Juneyoung Lee
Date: 2021-05-02T12:03:55+09:00
New Revision: 64e768e8162a3d32049ed5c38fd533beecb0c9af

URL: https://github.com/llvm/llvm-project/commit/64e768e8162a3d32049ed5c38fd533beecb0c9af
DIFF: https://github.com/llvm/llvm-project/commit/64e768e8162a3d32049ed5c38fd533beecb0c9af.diff

LOG: [ValueTracking] Improve impliesPoison to look into overflow intrinsics

This update supports the following transformation:

```
select(extract(mul_with_overflow(a, _), _), (a == 0), false)
=>
and(extract(mul_with_overflow(a, _), _), (a == 0))
```

which is correct because if `a` was poison the select's condition was
also poison.

This update is splitted from D101423.

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov-not.ll
    llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov.ll
    llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov-not.ll
    llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 369ac4220bea..e5b0345e7970 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 170b072dbdb6..57cef74aec7f 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 7d4744ccc584..bf86f43b5432 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 8468aa79830c..b039cc832f12 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 19d33f35106e..598ce5f2fa8d 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'


        


More information about the llvm-commits mailing list