diff options
| author | Dan Gohman <dan433584@gmail.com> | 2016-02-22 20:04:02 +0000 |
|---|---|---|
| committer | Dan Gohman <dan433584@gmail.com> | 2016-02-22 20:04:02 +0000 |
| commit | 3b09d279be164f3e9a16b18eced38ee75a00e6fe (patch) | |
| tree | d234074f36799119b3d5d148443d5c21eb8b1c8a /llvm/lib/Target | |
| parent | 56da313e866ddebe7f1188825346b0c31efd03fa (diff) | |
| download | bcm5719-llvm-3b09d279be164f3e9a16b18eced38ee75a00e6fe.tar.gz bcm5719-llvm-3b09d279be164f3e9a16b18eced38ee75a00e6fe.zip | |
[WebAssembly] Teach address folding to fold bitwise-or nodes.
LLVM converts adds into ors when it can prove that the operands don't share
any non-zero bits. Teach address folding to recognize or instructions with
constant operands with this property that can be folded into addresses as
if they were adds.
llvm-svn: 261562
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td index 096d1875492..a72da44f76c 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td @@ -28,6 +28,18 @@ def regPlusImm : PatFrag<(ops node:$addr, node:$off), (add node:$addr, node:$off), [{ return N->getFlags()->hasNoUnsignedWrap(); }]>; +// Treat an 'or' node as an 'add' if the or'ed bits are known to be zero. +def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ + if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) + return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue()); + + APInt KnownZero0, KnownOne0; + CurDAG->computeKnownBits(N->getOperand(0), KnownZero0, KnownOne0, 0); + APInt KnownZero1, KnownOne1; + CurDAG->computeKnownBits(N->getOperand(1), KnownZero1, KnownOne1, 0); + return (~KnownZero0 & ~KnownZero1) == 0; +}]>; + // GlobalAddresses are conceptually unsigned values, so we can also fold them // into immediate values as long as their offsets are non-negative. def regPlusGA : PatFrag<(ops node:$addr, node:$off), @@ -76,6 +88,14 @@ def : Pat<(f32 (load (regPlusImm I32:$addr, imm:$off))), (LOAD_F32 imm:$off, $addr, 0)>; def : Pat<(f64 (load (regPlusImm I32:$addr, imm:$off))), (LOAD_F64 imm:$off, $addr, 0)>; +def : Pat<(i32 (load (or_is_add I32:$addr, imm:$off))), + (LOAD_I32 imm:$off, $addr, 0)>; +def : Pat<(i64 (load (or_is_add I32:$addr, imm:$off))), + (LOAD_I64 imm:$off, $addr, 0)>; +def : Pat<(f32 (load (or_is_add I32:$addr, imm:$off))), + (LOAD_F32 imm:$off, $addr, 0)>; +def : Pat<(f64 (load (or_is_add I32:$addr, imm:$off))), + (LOAD_F64 imm:$off, $addr, 0)>; def : Pat<(i32 (load (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))), (LOAD_I32 tglobaladdr:$off, $addr, 0)>; @@ -188,6 +208,26 @@ def : Pat<(i64 (sextloadi32 (regPlusImm I32:$addr, imm:$off))), (LOAD32_S_I64 imm:$off, $addr, 0)>; def : Pat<(i64 (zextloadi32 (regPlusImm I32:$addr, imm:$off))), (LOAD32_U_I64 imm:$off, $addr, 0)>; +def : Pat<(i32 (sextloadi8 (or_is_add I32:$addr, imm:$off))), + (LOAD8_S_I32 imm:$off, $addr, 0)>; +def : Pat<(i32 (zextloadi8 (or_is_add I32:$addr, imm:$off))), + (LOAD8_U_I32 imm:$off, $addr, 0)>; +def : Pat<(i32 (sextloadi16 (or_is_add I32:$addr, imm:$off))), + (LOAD16_S_I32 imm:$off, $addr, 0)>; +def : Pat<(i32 (zextloadi16 (or_is_add I32:$addr, imm:$off))), + (LOAD16_U_I32 imm:$off, $addr, 0)>; +def : Pat<(i64 (sextloadi8 (or_is_add I32:$addr, imm:$off))), + (LOAD8_S_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (zextloadi8 (or_is_add I32:$addr, imm:$off))), + (LOAD8_U_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (sextloadi16 (or_is_add I32:$addr, imm:$off))), + (LOAD16_S_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (zextloadi16 (or_is_add I32:$addr, imm:$off))), + (LOAD16_U_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (sextloadi32 (or_is_add I32:$addr, imm:$off))), + (LOAD32_S_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (zextloadi32 (or_is_add I32:$addr, imm:$off))), + (LOAD32_U_I64 imm:$off, $addr, 0)>; def : Pat<(i32 (sextloadi8 (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))), (LOAD8_S_I32 tglobaladdr:$off, $addr, 0)>; @@ -332,6 +372,16 @@ def : Pat<(i64 (extloadi16 (regPlusImm I32:$addr, imm:$off))), (LOAD16_U_I64 imm:$off, $addr, 0)>; def : Pat<(i64 (extloadi32 (regPlusImm I32:$addr, imm:$off))), (LOAD32_U_I64 imm:$off, $addr, 0)>; +def : Pat<(i32 (extloadi8 (or_is_add I32:$addr, imm:$off))), + (LOAD8_U_I32 imm:$off, $addr, 0)>; +def : Pat<(i32 (extloadi16 (or_is_add I32:$addr, imm:$off))), + (LOAD16_U_I32 imm:$off, $addr, 0)>; +def : Pat<(i64 (extloadi8 (or_is_add I32:$addr, imm:$off))), + (LOAD8_U_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (extloadi16 (or_is_add I32:$addr, imm:$off))), + (LOAD16_U_I64 imm:$off, $addr, 0)>; +def : Pat<(i64 (extloadi32 (or_is_add I32:$addr, imm:$off))), + (LOAD32_U_I64 imm:$off, $addr, 0)>; def : Pat<(i32 (extloadi8 (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))), (LOAD8_U_I32 tglobaladdr:$off, $addr, 0)>; @@ -433,6 +483,14 @@ def : Pat<(store F32:$val, (regPlusImm I32:$addr, imm:$off)), (STORE_F32 imm:$off, I32:$addr, 0, F32:$val)>; def : Pat<(store F64:$val, (regPlusImm I32:$addr, imm:$off)), (STORE_F64 imm:$off, I32:$addr, 0, F64:$val)>; +def : Pat<(store I32:$val, (or_is_add I32:$addr, imm:$off)), + (STORE_I32 imm:$off, I32:$addr, 0, I32:$val)>; +def : Pat<(store I64:$val, (or_is_add I32:$addr, imm:$off)), + (STORE_I64 imm:$off, I32:$addr, 0, I64:$val)>; +def : Pat<(store F32:$val, (or_is_add I32:$addr, imm:$off)), + (STORE_F32 imm:$off, I32:$addr, 0, F32:$val)>; +def : Pat<(store F64:$val, (or_is_add I32:$addr, imm:$off)), + (STORE_F64 imm:$off, I32:$addr, 0, F64:$val)>; def : Pat<(store I32:$val, (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off))), (STORE_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>; @@ -528,6 +586,16 @@ def : Pat<(truncstorei16 I64:$val, (regPlusImm I32:$addr, imm:$off)), (STORE16_I64 imm:$off, I32:$addr, 0, I64:$val)>; def : Pat<(truncstorei32 I64:$val, (regPlusImm I32:$addr, imm:$off)), (STORE32_I64 imm:$off, I32:$addr, 0, I64:$val)>; +def : Pat<(truncstorei8 I32:$val, (or_is_add I32:$addr, imm:$off)), + (STORE8_I32 imm:$off, I32:$addr, 0, I32:$val)>; +def : Pat<(truncstorei16 I32:$val, (or_is_add I32:$addr, imm:$off)), + (STORE16_I32 imm:$off, I32:$addr, 0, I32:$val)>; +def : Pat<(truncstorei8 I64:$val, (or_is_add I32:$addr, imm:$off)), + (STORE8_I64 imm:$off, I32:$addr, 0, I64:$val)>; +def : Pat<(truncstorei16 I64:$val, (or_is_add I32:$addr, imm:$off)), + (STORE16_I64 imm:$off, I32:$addr, 0, I64:$val)>; +def : Pat<(truncstorei32 I64:$val, (or_is_add I32:$addr, imm:$off)), + (STORE32_I64 imm:$off, I32:$addr, 0, I64:$val)>; def : Pat<(truncstorei8 I32:$val, (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off))), |

