[llvm] 3cd67ee - [InstCombine] Drop range attr in select of ctz fold

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 4 06:48:18 PDT 2024


Author: Nikita Popov
Date: 2024-06-04T15:48:08+02:00
New Revision: 3cd67eeca28ab1084d02b7976de1af4c4c8d37d5

URL: https://github.com/llvm/llvm-project/commit/3cd67eeca28ab1084d02b7976de1af4c4c8d37d5
DIFF: https://github.com/llvm/llvm-project/commit/3cd67eeca28ab1084d02b7976de1af4c4c8d37d5.diff

LOG: [InstCombine] Drop range attr in select of ctz fold

The range may no longer be valid after the select has been
optimized away.

This fixes the kernel miscompiles reported at
https://github.com/ClangBuiltLinux/linux/issues/2031.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index a3ddb402bf662..a9aba550e3853 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1127,7 +1127,7 @@ static Instruction *foldSelectCtlzToCttz(ICmpInst *ICI, Value *TrueVal,
 /// into:
 ///   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
 static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
-                                 InstCombiner::BuilderTy &Builder) {
+                                 InstCombinerImpl &IC) {
   ICmpInst::Predicate Pred = ICI->getPredicate();
   Value *CmpLHS = ICI->getOperand(0);
   Value *CmpRHS = ICI->getOperand(1);
@@ -1169,6 +1169,9 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
     // Explicitly clear the 'is_zero_poison' flag. It's always valid to go from
     // true to false on this flag, so we can replace it for all users.
     II->setArgOperand(1, ConstantInt::getFalse(II->getContext()));
+    // A range annotation on the intrinsic may no longer be valid.
+    II->dropPoisonGeneratingAnnotations();
+    IC.addToWorklist(II);
     return SelectArg;
   }
 
@@ -1921,7 +1924,7 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
   if (Value *V = foldSelectICmpLshrAshr(ICI, TrueVal, FalseVal, Builder))
     return replaceInstUsesWith(SI, V);
 
-  if (Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, Builder))
+  if (Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *this))
     return replaceInstUsesWith(SI, V);
 
   if (Value *V = canonicalizeSaturatedSubtract(ICI, TrueVal, FalseVal, Builder))

diff  --git a/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll b/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll
index eac46856bb4b5..35b4087d767a7 100644
--- a/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll
+++ b/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll
@@ -49,10 +49,9 @@ define i16 @test4(i16 %x) {
   ret i16 %cond
 }
 
-; FIXME: This is a miscompile.
 define i16 @test4_with_range(i16 %x) {
 ; CHECK-LABEL: @test4_with_range(
-; CHECK-NEXT:    [[CT:%.*]] = call range(i16 0, 16) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
+; CHECK-NEXT:    [[CT:%.*]] = call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
 ; CHECK-NEXT:    ret i16 [[CT]]
 ;
   %ct = call range(i16 0, 16) i16 @llvm.ctlz.i16(i16 %x, i1 true)
@@ -127,10 +126,9 @@ define i16 @test4b(i16 %x) {
   ret i16 %cond
 }
 
-; FIXME: This is a miscompile.
 define i16 @test4b_with_range(i16 %x) {
 ; CHECK-LABEL: @test4b_with_range(
-; CHECK-NEXT:    [[CT:%.*]] = call range(i16 0, 16) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
+; CHECK-NEXT:    [[CT:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
 ; CHECK-NEXT:    ret i16 [[CT]]
 ;
   %ct = call range(i16 0, 16) i16 @llvm.cttz.i16(i16 %x, i1 true)


        


More information about the llvm-commits mailing list