visitSwitchInst generates SUB constant expressions to recompute the switch
condition. When truncating the condition to a smaller type, SUB expressions
should use the previous type (before trunc) for both operands. This fixes an
assertion crash.
Details
Diff Detail
Event Timeline
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2107–2108 | InstCombine methods are supposed to return the original instruction if they modify the instruction. It seems visitSwitchInst isn't doing this here. | |
2120–2123 | Isn't this equivalent to: | |
2124 | Might as well make this Constant * since you are changing the right hand side. | |
2124 | Might as well put the pointer on the right hand side. |
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2107–2108 | Good catch, in case where Trunc instruction is generated but no ADD instruction is found we're returning null. Will address that in a next patch since this is not related to this fix. | |
2120–2123 | Likely, but only after a series of constant fold lookups/calls for the common cases, I guess the current version is uglier but faster. | |
2124 | Ok! |
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2122 | Is there any particular reason why you chose to sext instead of zext? |
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2122 | Being conservative to perform the right extension when coming back from the truncated negative condition cases. Would that be somehow redundant in this scenario? |
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2122 | I don't think it will actually be faster. ConstantExpr::getSExt(CaseVal, Cond->getType()) will call getFoldedCast which will call ConstantFoldCastInstruction which will do the following: case Instruction::SExt: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); return ConstantInt::get(V->getContext(), CI->getValue().sext(BitWidth)); } Seems like it will do the exact same thing. No table lookups involved. |
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2122 | As I said before, it takes additional calls for every case statement. We don't need to bikeshed on that though, I guess that won't make that much difference either. |
LGTM with the above changes and one comment (I'd make it inline but parts of the diff are missing).
Would it be reasonable to zext instead of sext if the bits you trimmed off were all zeros?
lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
2121 | ConstantExpr::getSExt returns a Constant *, the cast<Constant> should be redundant. | |
2122–2123 | Likewise. Also, please stick the pointer on the RHS. |
InstCombine methods are supposed to return the original instruction if they modify the instruction. It seems visitSwitchInst isn't doing this here.