[X86] Teach constant hoisting that ANDs with 64-bit immediates in the range 0x8000000...
authorCraig Topper <craig.topper@gmail.com>
Tue, 6 Oct 2015 02:50:24 +0000 (02:50 +0000)
committerCraig Topper <craig.topper@gmail.com>
Tue, 6 Oct 2015 02:50:24 +0000 (02:50 +0000)
Most importantly, this keeps constant hoisting from preventing instruction selections ability to turn an AND with 0xffffffff into a move into a 32-bit subregister.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249370 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86TargetTransformInfo.cpp
test/CodeGen/X86/constant-hoisting-and.ll [new file with mode: 0644]

index f230570..7f1db70 100644 (file)
@@ -1078,6 +1078,13 @@ int X86TTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
   case Instruction::Store:
     ImmIdx = 0;
     break;
+  case Instruction::And:
+    // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
+    // by using a 32-bit operation with implicit zero extension. Detect such
+    // immediates here as the normal path expects bit 31 to be sign extended.
+    if (Idx == 1 && Imm.getBitWidth() == 64 && isUInt<32>(Imm.getZExtValue()))
+      return TTI::TCC_Free;
+    // Fallthrough
   case Instruction::Add:
   case Instruction::Sub:
   case Instruction::Mul:
@@ -1085,7 +1092,6 @@ int X86TTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
   case Instruction::SDiv:
   case Instruction::URem:
   case Instruction::SRem:
-  case Instruction::And:
   case Instruction::Or:
   case Instruction::Xor:
   case Instruction::ICmp:
diff --git a/test/CodeGen/X86/constant-hoisting-and.ll b/test/CodeGen/X86/constant-hoisting-and.ll
new file mode 100644 (file)
index 0000000..611445f
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llc < %s -O3 -march=x86-64 |FileCheck %s
+define i64 @foo(i1 %z, i64 %data1, i64 %data2)
+{
+; If constant 4294967294 is hoisted to a variable, then we won't be able to use
+; the implicit zero extension of 32-bit operations to handle the AND.
+entry:
+  %val1 = and i64 %data1, 4294967294
+  br i1 %z, label %End, label %L_val2
+
+; CHECK: andl    $-2, {{.*}}
+; CHECK: andl    $-2, {{.*}}
+L_val2:
+  %val2 = and i64 %data2, 4294967294
+  br label %End
+
+End:
+  %p1 = phi i64 [%val1,%entry], [%val2,%L_val2]
+  ret i64 %p1
+}