From 7fa150203f882bd7e4fbbfcff4580efe84d036c9 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 1 May 2020 13:51:21 -0400 Subject: [PATCH] [InstCombine] fix miscompile from multi-use cttz/ctlz transform PR45762: https://bugs.llvm.org/show_bug.cgi?id=45762 --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 9 +++++---- llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index a5d11ce..b9d3274 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -883,10 +883,11 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal, return SelectArg; } - // If the ValueOnZero is not the bitwidth, we can at least make use of the - // fact that the cttz/ctlz result will not be used if the input is zero, so - // it's okay to relax it to undef for that case. - if (II->hasOneUse() && !match(II->getArgOperand(1), m_One())) + // The ValueOnZero is not the bitwidth. But if the cttz/ctlz (and optional + // zext/trunc) have one use (ending at the select), the cttz/ctlz result will + // not be used if the input is zero. Relax to 'undef_on_zero' for that case. + if (II->hasOneUse() && SelectArg->hasOneUse() && + !match(II->getArgOperand(1), m_One())) II->setArgOperand(1, ConstantInt::getTrue(II->getContext())); return nullptr; diff --git a/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll b/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll index e0cd667..44d284c 100644 --- a/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll +++ b/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll @@ -220,7 +220,7 @@ define <2 x i32> @select_clz_to_ctz_vec_with_undef(<2 x i32> %a) { define i4 @PR45762(i3 %x4) { ; CHECK-LABEL: @PR45762( -; CHECK-NEXT: [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 true), !range !2 +; CHECK-NEXT: [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false), !range !2 ; CHECK-NEXT: [[T7:%.*]] = zext i3 [[T4]] to i4 ; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl i4 1, [[T7]] ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i3 [[X4]], 0 -- 2.7.4