-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Open
Description
this function:
declare i7 @llvm.cttz.i7(i7, i1 immarg)
define i7 @f(i7 %0) {
%2 = call i7 @llvm.cttz.i7(i7 %0, i1 false)
%3 = icmp eq i7 %0, 0
%4 = select i1 %3, i7 0, i7 %2
ret i7 %4
}
is getting miscompiled by the RISCV64+B backend as:
f:
ori a0, a0, 128
ctz a0, a0
andi a0, a0, 6
ret
the 6
in the output doesn't make sense, it is coming from an insufficiently-protected Bitwidth - 1
.
@MitchBriles, a student working with me, has the following candidate patch. it certainly fixes this case but we've not fully vetted it yet. actually, if nobody is in a rush to fix this, Mitch would like to be the one to submit the PR for it.
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4a1db80076..7a5ebf74c4 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -18740,6 +18740,10 @@ static SDValue foldSelectOfCTTZOrCTLZ(SDNode *N, SelectionDAG &DAG) {
if (Cond->getOperand(0) != CountZeroesArgument)
return SDValue();
+ unsigned BitWidth = CountZeroes.getValueSizeInBits();
+ if (!isPowerOf2_32(BitWidth))
+ return SDValue();
+
if (CountZeroes.getOpcode() == ISD::CTTZ_ZERO_UNDEF) {
CountZeroes = DAG.getNode(ISD::CTTZ, SDLoc(CountZeroes),
CountZeroes.getValueType(), CountZeroesArgument);
@@ -18748,7 +18752,6 @@ static SDValue foldSelectOfCTTZOrCTLZ(SDNode *N, SelectionDAG &DAG) {
CountZeroes.getValueType(), CountZeroesArgument);
}
- unsigned BitWidth = CountZeroes.getValueSizeInBits();
SDValue BitWidthMinusOne =
DAG.getConstant(BitWidth - 1, SDLoc(N), CountZeroes.getValueType());
lenary, dtcxzyw and topperc