From: Thomas Lively Date: Sun, 5 Jul 2020 01:11:24 +0000 (-0700) Subject: [WebAssembly] Do not assume br_table range checks will be gt_u X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=65330f394b2c5ede01acb97a84112c3cc0127c46;p=android-x86%2Fexternal-llvm-project.git [WebAssembly] Do not assume br_table range checks will be gt_u OSS-Fuzz and the Emscripten test suite uncovered some edge cases in which the range check instruction seemed to be an (i32.const 0) or other unexpected instruction, triggering an assertion. Unfortunately the reproducers are rather complicated, so they don't make good unit tests. This commit removes the bad assertion and conservatively optimizes range checks only when the range check instruction is i32.gt_u. Differential Revision: https://reviews.llvm.org/D83169 --- diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFixBrTableDefaults.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFixBrTableDefaults.cpp index 2d657130848..5de4d440e4f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFixBrTableDefaults.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFixBrTableDefaults.cpp @@ -76,17 +76,15 @@ MachineBasicBlock *fixBrTable(MachineInstr &MI, MachineBasicBlock *MBB, // If the range check checks an i64 value, we cannot optimize it out because // the i64 index is truncated to an i32, making values over 2^32 - // indistinguishable from small numbers. + // indistinguishable from small numbers. There are also other strange edge + // cases that can arise in practice that we don't want to reason about, so + // conservatively only perform the optimization if the range check is the + // normal case of an i32.gt_u. MachineRegisterInfo &MRI = MF.getRegInfo(); auto *RangeCheck = MRI.getVRegDef(Cond[1].getReg()); assert(RangeCheck != nullptr); - unsigned RangeCheckOp = RangeCheck->getOpcode(); - assert(RangeCheckOp == WebAssembly::GT_U_I32 || - RangeCheckOp == WebAssembly::GT_U_I64); - if (RangeCheckOp == WebAssembly::GT_U_I64) { - // Bail out and leave the jump table untouched + if (RangeCheck->getOpcode() != WebAssembly::GT_U_I32) return nullptr; - } // Remove the dummy default target and install the real one. MI.RemoveOperand(MI.getNumExplicitOperands() - 1);