GBE: fix a bool handling bug when SEL on a uniform bool variable.
authorZhigang Gong <zhigang.gong@intel.com>
Wed, 5 Nov 2014 07:36:23 +0000 (15:36 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Thu, 6 Nov 2014 07:15:53 +0000 (15:15 +0800)
If a SEL uses a bool variable which is a uniform bool, even
we can get a dag node within the same BB, we still need to
set the externFlag bit. The reason is that we don't know how
to generate a scalar physical flag.

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
Reviewed-by: "Song, Ruiling" <ruiling.song@intel.com>
backend/src/backend/gen_insn_selection.cpp
backend/src/backend/gen_reg_allocation.cpp

index 64e9fd8..b682d5c 100644 (file)
@@ -1604,9 +1604,10 @@ namespace gbe
           // Check whether this bool is used as a normal source
           // oprand other than BRA/SEL.
           if (getRegisterFamily(reg) == FAMILY_BOOL) {
-            if (insn.getOpcode() != OP_BRA &&
+            if ((insn.getOpcode() != OP_BRA &&
                  (insn.getOpcode() != OP_SEL ||
-                   (insn.getOpcode() == OP_SEL && srcID != 0)))
+                 (insn.getOpcode() == OP_SEL && srcID != 0))) ||
+               (isScalarReg(reg)))
               child->computeBool = true;
           }
           child->isUsed = true;
@@ -3804,7 +3805,16 @@ namespace gbe
         sel.curr.physicalFlag = 0;
         sel.curr.flagIndex = (uint16_t) pred;
         sel.curr.predicate = GEN_PREDICATE_NORMAL;
-        if (!dag0)
+        // FIXME in general, if the flag is a uniform flag.
+        // we should treat that flag as extern flag, as we
+        // never genrate a uniform physical flag. As we can
+        // never predicate which channel is active when this
+        // flag is used.
+        // We need to concentrate this logic to the modFlag bit.
+        // If an instruction has that bit, it will generate physical
+        // flag, otherwise it will not. But current modFlag is
+        // just a hint. We need to fix it in the future.
+        if (!dag0 || (sel.isScalarReg(dag0->insn.getDst(0))))
           sel.curr.externFlag = 1;
         if(type == ir::TYPE_S64 || type == ir::TYPE_U64)
           sel.SEL_INT64(dst, src0, src1);
index ef519d9..18f60ca 100644 (file)
@@ -585,6 +585,8 @@ namespace gbe
               // If this is a modFlag on a scalar bool, we need to remove it
               // from the allocated flags map. Then latter, the user could
               // validate the flag from the scalar value correctly.
+              // The reason is we can not predicate the active channel when we
+              // need to use this flag.
               if (IS_SCALAR_FLAG(insn)) {
                 allocatedFlags.erase(ir::Register(insn.state.flagIndex));
                 continue;